这个很简单。Printf的奇怪输出无符号长整数
printf("%lu\n", (unsigned long)(320 * 200));
该行代码打印出“4294965760”。这绝对不等于360 * 200.它有什么问题?
我在16位中型内存模型中使用了Digital Mars C编译器。
这个很简单。Printf的奇怪输出无符号长整数
printf("%lu\n", (unsigned long)(320 * 200));
该行代码打印出“4294965760”。这绝对不等于360 * 200.它有什么问题?
我在16位中型内存模型中使用了Digital Mars C编译器。
在16位系统中,如果sizeof(int) == 2
,然后320 * 200
,这等于64000
,太大的签署int
(范围±32,767 - 通常-32,768过,但在理论上它因平台而异)。所以,你有算术溢出。演员阵容不会影响乘法;它只影响乘法结果发生的情况。
你会做的更好:
printf("%lu\n", 320UL * 200UL);
,迫使常量unsigned long
。
我不明白?那不是我所拥有的?每个人从哪里得到“签名的Int”?我清楚地将320 * 200类型转换为4字节的unsigned long int,并使用“%lu”表示将unsigned long int打印出来。 – SeanRamey
这工作!但为什么?我不明白吗?常数和类型转换有什么不同? – SeanRamey
320是一个(带符号)'int'值。 200是一个(带符号)'int'值。当编译器看到“320 * 200”时,它必须乘以两个(带符号)“int”值,这会产生(符号和溢出)“int”值。然后,当它完成时,它必须将结果(溢出(带符号)的'int'值)转换为'unsigned long'。溢出的值是负值;这意味着一个很大的'无符号长'值。你可以使用'320U * 200U',因为'64000'小于'65535',最大16位'unsigned int',并将其转换为'unsigned long'也会干净。 –
我刚刚在我的代码中试过这个,我得到64000. 也许问题是320*200
是一个有符号数!当你投掷它时,他们在比特级有问题吗?尝试
unsigned long x = 320*200;
printf("%lu\n", x);
//64000 = 0b1111101000000000
//4294965760 = 0b11111111111111111111101000000000
看到第一位匹配!所以这可能是演员的问题。
[无法重现您的结果](http://ideone.com/5DEcfs) – dasblinkenlight
您将*结果*转换为'320 * 200',但这是64000和64000不符合带符号的16位整数未定义的行为)。不用'320 * 200'附近的圆括号再试一次。如果仍然失败:诅咒编译器。 – deamentiaemundi
但是一个无符号长整数不是一个16位整数,它是无符号的。这是一个4字节的int,这意味着32位......所以诅咒编译器? – SeanRamey