为什么1024*1024*1024*2!= 1024*1024*1024*2

nic*_*ick 3 c integer-overflow

在开始时,我写了一个演示来获得2G内存,但我遇到了这样的问题,我不知道为什么,num1,num2,num3有什么不同?

#include<stdio.h>
int main(){
    unsigned long num1 = 1024*1024*1024*2;
    unsigned long num2 = 1024*1024*1024*2.0;
    unsigned long num3 = 1024*1024*1024;
    num3 *= 2;
    printf("num1:%lu\n num2:%lu\n num3:%lu\n", num1, num2, num3);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

num1:18446744071562067968
num2:2147483648
num3:2147483648
Run Code Online (Sandbox Code Playgroud)

Nel*_*eal 7

第一行用一个unsigned long num1 = 1024*1024*1024*2;初始化一个unsigned long(num1)int.计算1024*1024*1024*2具有类型,int因为所有值都是int文字.UL在其中至少有一个上使用后缀来实现unsigned long:

unsigned long num1 = 1024UL*1024*1024*2;
Run Code Online (Sandbox Code Playgroud)

作为预防措施,您可以选择将后缀放在第一个值上,因为乘法的从左到右相关性.这样,所有这些乘法都是在类型的值之间完成unsigned long而不是int.

至于为什么其他两种方法有效:第二行num2用a 初始化,double在这种情况下具有足够的精度来产生正确的值; 第三行也num3用a 初始化int,但是1024*1024*1024可以用32位表示int(它是2 ^ 30,小于2 ^ 31-1).之后乘以2乘以a unsigned long,因此它按预期工作.