【问题标题】:why this would result in long integer overflow为什么这会导致长整数溢出
【发布时间】:2011-12-07 16:44:36
【问题描述】:

我检查了long= int64 的范围超过 900,000,000,000,000 的文档

这是我的代码:

int r = 99;
long test1 = r*r*r*r*r;

在运行时它给我 919,965,907 而不是正确的 9,509,900,499。

另一个测试

long test2 = 99*99*99*99*99;

它拒绝编译,说整数溢出。

但如果我这样做

long test3 = 10100200300;

这很好用。

【问题讨论】:

    标签: c# integer


    【解决方案1】:

    问题是文字“99”被视为一个int。如果您添加“L”,它将把它视为一个长。要解决您的编译问题:

    long test2 = 99L * 99L * 99L * 99L * 99L;
    

    以及修复整数溢出导致的“错误结果”:

    long r = 99;
    long test1 = r * r * r * r * r;
    

    关键是“=”右侧的表达式在之前long r的赋值完成。

    您可能对其他文字后缀感兴趣:

    Type    Suffix    Example
    uint    U or u    100U
    long    L or l    100L
    ulong   UL or ul  100UL
    float   F or f    123.45F
    decimal M or m    123.45M
    

    @m.edmonson,关于您为什么会出现 919965907 的问题。发生的事情是该值“包裹”在 int.MaxValue 周围。您可以通过一个小测试程序看到这一点:

    int i = 99; // 99
    i *= 99;    // 9801
    i *= 99;    // 970299
    i *= 99;    // 96059601
    i *= 99;    // 919965907        should be 9509900499 but comes out to 919965907
                //                      which is (9509900499 % int.MaxValue)
    
    long k = 9509900499 % int.MaxValue;
    

    什么是“环绕”?当您超过int.MaxValue 1 时,该值“返回”到int.MinValue

    int j = int.MaxValue;
    j++;
    
    bool isNowMinValue = (j == int.MinValue);   // true, the value has "wrapped around"
    

    这有点简单;如果您搜索“整数溢出”,您将得到更好的解释。值得了解整数(和其他数字类型)如何用 32 位表示:

    http://en.wikipedia.org/wiki/Signed_number_representations

    【讨论】:

    • 很好的答案 - 你能解释为什么他在长整数乘法和整数乘法之间得到不同的结果吗?
    • 你能澄清一下你所说的包装是什么意思吗?那与模数 % 有什么关系?
    • 我相信你只需要一个99L,其余的都会向上。
    • s/upcast/进行积分提升/
    • Int 值未环绕“int.MaxValue”,公式“9509900499 % int.MaxValue”不正确。正确的公式是:“(9509900499 + int.MaxValue + 1) % ((long)int.MaxValue - int.MinValue + 1) - int.MaxValue - 1”
    【解决方案2】:

    它使用整数乘法:

    long r = 99;
    long test1 = r*r*r*r*r;
    

    【讨论】:

      【解决方案3】:

      正如其他人所说,但是:

      long test2 = 99L * 99 * 99 * 99 * 99;
      

      这将为您提供正确的结果,并减少 L 周围 :-)

      发生这种情况是因为第一个 99L 是long,所以所有乘法都在long“字段”中完成,并且所有其他整数在乘法之前向上转换为long(显然,乘法总是介于2 个数字,从左到右,所以就像 (((99L * 99) * 99) * 99) * 99 并且每个“部分”结果都是一个长整数,并导致下一个操作数被转换为长整数。)

      【讨论】:

        【解决方案4】:

        你的第二个测试失败了,因为每个 99 都是一个整数;将其替换为以下内容即可编译。

        long test2 = 99L * 99L * 99L * 99L * 99L;
        

        详情请参阅MSDN Long Documentation

        【讨论】:

          【解决方案5】:

          编译器将 99 视为整数,即使最终结果很长。

          这会起作用。

          long test2 = 99L*99L*99L*99L*99L;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-12-20
            • 2018-10-11
            • 1970-01-01
            • 2021-12-16
            • 1970-01-01
            • 2016-01-22
            相关资源
            最近更新 更多