有人可以解释为什么以下代码总共为0? 这如何加起来为零?我使用不同的类型获得相同的结果,例如long和long long。谢谢!
int num;
num = (256 * 256 * 256 * 256)-1; //-1 warning C4307: '*': integral constant overflow
cout << num << endl;
num = 256 * 256 * 256 * 256; //0 warning C4307: '*': integral constant overflow
cout << num << endl;
num = (256 * 256) * (256 * 256); //0 warning C4307: '*': integral constant overflow
cout << num << endl;
num = (256 * (256 * 256) * 256); //0 warning C4307: '*': integral constant overflow
cout << num << endl;
num = 256 * 256 * 256; // 16777216
cout << num << endl;
num = 256 * 256; //65536
cout << num << endl;
输出:
-1
0
0
0
16777216个
65536
更改类型仅影响: num = 256 * 256; num = num * 256 * 256; 加起来正确。
long long num;
num = (256L * 256L * 256L * 256L)-1; //warning C4307: '*': integral constant overflow
cout << num << endl;
num = (256L * 256L * 256L * 256L); //warning C4307: '*': integral constant overflow
cout << num << endl;
num = (256 * 256) * (256 * 256); //warning C4307: '*': integral constant overflow
cout << num << endl;
num = (256 * (256 * 256) * 256); //warning C4307: '*': integral constant overflow
cout << num << endl;
num = 256 * 256 * 256;
cout << num << endl;
num = 256 * 256;
cout << num << endl;
num = num * 256 * 256;
cout << num << endl;
cout << sizeof(int) << endl;
cout << sizeof(long long) << endl;
输出:
-1
0
0
0
16777216个
65536个
4294967296个
sizeof(int)4
sizeof(long long)8
我想这与&#39; *&#39;的数量有关。乘法运算符。数学运算3或更少。
答案 0 :(得分:2)
即使目标变量是long long
,表达式的所有部分都是(32位)int。无论你如何尝试对乘法进行分组,结果都是2 ** 32,其低32位为0.
答案 1 :(得分:2)
256 = 2 8 和
256 * 256 * 256 * 256
= 2 8 * 2 8 * 2 8 * 2 8
= 2 (8 + 8 + 8 + 8)
= 2 32
然而(根据您的错误),您的机器支持int
s在-2 31 到2 31 - 1范围内。
所以2 32 导致溢出,导致0,因为除了MSB之外的所有位都是0。
答案 2 :(得分:2)
为什么
warning C4307: '*': integral constant overflow
?
文字256
的默认大小为4个字节,涉及4个字节整数的算术运算结果将被分配为 4个字节 。所以:
256 in hex notation is 0x100
256 * 256 * 256 * 256
= 0x100 * 0x100 * 0x100 * 0x100
= 0x 01 00 00 00 00 //Too big for 4 bytes, therefore overflow
为什么
256 * 256 * 256 * 256 == 0
?
从上面继续。
//The result of the calculation is **mashed** into 4 bytes
0x 01 00 00 00 00
^^^^^^^^^^^
//The last 4 bytes == 0 and this is the value assigned to num
此时num
被声明为8字节整数(long long
):
0
是结果 (以4个字节为单位)。0
将分配到num
。将您的文字声明为 8字节值(即256LL
),计算结果也应为8个字节。
long long num = 256LL * 256LL * 256LL * 256LL;
注意:原始类型的大小限制是软件开发中的标准问题。如果使用8字节整数,则仍然限制为最大可能的8字节值,即2 64 -1。有关详细信息,请阅读有关整数类型here的部分。
如果您需要任意大数字,则需要使用提供此类功能的库。
答案 3 :(得分:2)
我们的号码系统(我们写的)以十进制(基数10)存储数字,其中每个数字可以采用10个不同的值(0-9)。如果你有一个只有6位数的计算器,你可以显示的最大数字是999999.如果你尝试乘以1000 * 1000你会得到一个错误,或者计算器必须摆脱6位以上的数字或两者兼而有之。 / p>
计算机以二进制(基数2)存储数字。 C(和C ++)定义了几个data types,用于定义数字的存储方式。 Microsoft C++ (VCPP) further clarifies these。对于有符号整数,它们是:
short
(最小16位)MSVCPP = 16位int
(最小16位)MSVCPP = 32位long
(最小32位)MSVCPP = 32位 long long
(最小64位)MSVCPP = 64位
请注意“&#39;通常&#39;因为C标准设定了最小尺寸但不是最大尺寸
另请注意:我知道我跳过了char,因为(恕我直言)它有点混合型。
还有一些无符号类型用于交换符号位以获得额外的数字,因此它们可以存储更大(正)的数字。
好的,回到你的问题。
由于@Coldspeed提到256 = 2 8 。在二进制中,需要10位表示有符号数,9位表示无符号。这很容易适合任何这些类型。当你得到256 * 256 * 256 * 256 = 2 32 时,这将需要34位,只适合long long
。就像在6位数计算器上一样,您将得到松散高位数或两者都错误的错误。在这种情况下,丢失高位数将导致&#39; 0&#39;。
这解释了你的前四个答案(第一个,认为0-1 = -1)
但为什么没有long long
工作。答案是,这只是存储最终结果的地方。除非另有说明,否则所有整数文字(数字)都将被视为int
类型;因此,在将数字放入num
之前计算中的计算期间发生截断/错误。
最后两个在C&#39; C&#39;因为它们可能会导致错误,因为结果大于short
可以容纳,int
不能保证大于short
;但是,对于MSVCPP,它是(32位)。