C Printf Unsigned Long的奇怪输出

C Printf Unsigned Long的奇怪输出,c,printf,multiplication,16-bit,C,Printf,Multiplication,16 Bit,这个很简单 printf("%lu\n", (unsigned long)(320 * 200)); 这行代码打印出“4294965760”。这绝对不等于360*200。怎么了 我在16位介质内存模型中使用数字Mars C编译器。我刚刚在代码中尝试了这个,得到了64000。 也许问题在于320*200是一个有符号的数字!当你施法的时候,他们在比特级有问题吗?试一试 unsigned long x = 320*200; printf("%lu\n", x); //64000 =

这个很简单

printf("%lu\n", (unsigned long)(320 * 200));
这行代码打印出“4294965760”。这绝对不等于360*200。怎么了


我在16位介质内存模型中使用数字Mars C编译器。

我刚刚在代码中尝试了这个,得到了64000。 也许问题在于
320*200
是一个有符号的数字!当你施法的时候,他们在比特级有问题吗?试一试

unsigned long x = 320*200;
printf("%lu\n", x);
//64000 =                      0b1111101000000000
//4294965760 = 0b11111111111111111111101000000000

确保第一位匹配!所以这可能是演员阵容的问题

在16位系统上,如果
sizeof(int)=2
,则等于
64000
320*200
对于有符号
int
(范围±32767-通常也为-32768,但理论上它因平台而异)太大。所以,你有算术溢出。施法不影响乘法运算;它只影响乘法的结果

你最好在以下方面做得更好:

printf("%lu\n", 320UL * 200UL);

这将强制常量为无符号长

您强制转换“320*200”的结果,但结果为64000,64000不适合有符号16位整数(未定义行为)。请重试,不要在
320*200
周围加括号。如果它仍然失败:诅咒编译器。但是无符号long不是16位整数,它是无符号的。它是一个4字节的整数,意思是32位。。。所以诅咒编译器???@SeanRamey,但你不使用它,你使用16位有符号整数,因为“320'200”附近有括号。啊,有人能够重复这种行为,所以请看纳齐姆·莱克哈尔的回答。还有:是的,诅咒编译器,它应该警告你。@SeanRamey:不-不要诅咒编译器。(或者,至少,编译器是无辜的。)您的问题是乘法是在转换为
无符号长
之前完成的,并且您正在将溢出的16位有符号量转换为
无符号长
,这是一个错误。错误在你的代码中;编译器很少出错。它确实发生了。这不常发生,我不明白?这不是我所拥有的吗??每个人从哪里得到“签名整数”??很明显,我正在将320*200类型转换为4字节的无符号长整型,并使用“%lu”表示打印无符号长整型。这很有效!但是为什么呢?我不明白?常量和类型转换有什么不同?320是一个(有符号)
int
值。200是一个(有符号)
int
值。当编译器看到
320*200
时,它必须将两个(有符号的)
int
值相乘,从而产生一个(有符号且溢出的)
int
值。然后,当它这样做时,它必须将结果(溢出(有符号)
int
值)转换为
无符号long
。溢出值为负值;这将转换为一个大的
无符号long
值。您可能可以使用
320U*200U
,因为
64000
小于
65535
,所以最大16位
无符号整数
,将其转换为
无符号长
也将是干净的。所有足够小的常量都有符号
int
,是的。如果常量太大,无法放入带符号的
int
,则十进制常量将被视为
long
long
(它将装入的较小常量)。八进制和十六进制常量也可以变为
无符号int
,或
无符号long
无符号long
,具体取决于值的大小。有关详细信息,请参见C标准中的第6.4.4.1节整型常量-其中有一个表定义了我在这里总结的内容。顺便说一句,您所说的“16位介质内存模型中的Digital Mars C编译器”非常重要,也非常有帮助,这使我能够为您推断出这个答案。谢谢你提供这些信息。