使用不同的表达式计算相同的整数时,结果不一致。

时间:2019-04-13 16:08:41

标签: c++ integer-arithmetic unsigned-long-long-int

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

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 是预期的答案(由Google计算器针对所有四个表达式给出)。

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

2 个答案:

答案 0 :(得分:2)

初始化代码include();遭受带符号整数溢出(即“未定义行为”)以及带符号int到无符号的隐式转换的困扰。虽然分步计算可以避免这些问题,因为右手操作数会隐式转换为unsigned long long。

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

# For security reasons, Option followsymlinks cannot be overridden.
#Options +FollowSymlinks -MultiViews
Options +SymLinksIfOwnerMatch -MultiViews
RewriteEngine On
RewriteBase /

# http -> https
RewriteCond %{HTTP_HOST} s8w\.org [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L,NE]

# skip files and directories from rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]

RewriteRule ^category/(.*)$ category.php?title=$1 [QSA,L,NC]

RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

RewriteRule ^(.+)$ index.php?title=$1 [QSA,L]

答案 1 :(得分:0)

这是因为您没有使用unsigned long long文字。如果要使文字与定义相匹配,则需要使用:

255ULL + 256ULL * 255ULL + ...

如果创建64位数字,则ULL非常重要。在C语言中,不带后缀的数字可能是64位,32位甚至16位(甚至在某些CRAY中为64位的字节。这也意味着您的代码只在那些CRAY系统之一上就可以工作了。)