首页 > 解决方案 > 使用不同表达式计算相同整数时的不一致结果

问题描述

相同表达式的算术结果会导致不同的结果,这取决于我是在一行中定义一个整数还是我使用了几个步骤:

int main() {

    unsigned long long veryBigIntOneLine = ((255*256+255)*256+255)*256+255;

    unsigned long long veryBigInt = 255;
    veryBigInt *= 256;
    veryBigInt += 255;
    veryBigInt *= 256;
    veryBigInt += 255;
    veryBigInt *= 256;
    veryBigInt += 255;

    unsigned long long veryBigIntParanthesis = (((((255*256)+255)*256)+255)*256)+255;

    unsigned long long fourthInt = 256;
    fourthInt *= 256;
    fourthInt *= 256;
    fourthInt *= 256;
    --fourthInt;

    cout << "veryBigIntOneLine: " << veryBigIntOneLine << endl;
    cout << "veryBigInt: " << veryBigInt << endl;
    cout << "veryBigIntParanthesis: " << veryBigIntParanthesis << endl;
    cout << "fourthInt: " << fourthInt << endl;

    return 0;

}

它们都应该描述相同的数字256^4-1(或2^32-1),但结果不同。

veryBigIntOneLine: 18446744073709551615
veryBigInt: 4294967295
veryBigIntParanthesis: 18446744073709551615
fourthInt: 4294967295

4294967295是预期的答案(因为它是由谷歌计算器给出的所有四个表达式)。

此外,18446744073709551615可能不是计算结果的确切结果,因为我在编译时对两个单行表达式都收到了溢出警告(即使我尝试使用 __int128 类型)。它实际上是2^64-1 ,这是我的编译器unsigned long long的最大值( veryBigIntOneLine+1 给出 0)。

标签: c++integer-arithmeticunsigned-long-long-int

解决方案


初始化代码((255*256+255)*256+255)*256+255遭受有符号整数溢出(未定义行为)以及有符号整数到无符号的隐式转换。而逐步计算避免了这些问题,因为右手操作数被隐式转换为 unsigned long long。

只需使用适当的文字就可以解决这些问题:

unsigned long long veryBigIntOneLine{ ((255ull*256ull+255ull)*256ull+255ull)*256ull+255ull}; // 4294967295

推荐阅读