我有问题。在此程序中,变量x应设置为0x10000,但在两个操作中结果为0.
这不是主程序,而是查找错误原因的测试。我目前正在使用十六进制输入制作64位乘法器。我使用Keil和Proteus
进行了16位乘法运算int main() {
unsigned long int x = 0;
x = 0x8000 * 0x2;
x = 0x8000 + 0x8000;
return 0;
}
答案 0 :(得分:6)
文字0x8000
的类型为 unsigned int
。在您的16位计算机上,int
因此unsigned int
的自然大小为16位,是C标准接受的最小值。整数提升规则表示较小的宽度类型被扩展为int
或unsigned int
,但不再进一步(C11 n1570 6.3.1.1p2):
如果
int
可以表示原始类型的所有值(受宽度限制,对于位字段),则该值将转换为int
;否则,它将转换为unsigned int
。这些被称为整数促销。 58)所有其他类型由整数促销保持不变。
仅当其他操作数的排名更高时,操作数才会从int
或unsigned int
加宽。
此处,0x8000
+ 0x8000
使用unsigned int
计算,它将换行为0,因为unsigned int
中可以表示的最大值为0xFFFF
您应该使用后缀unsigned long
强制执行至少一个操作数 UL
,或者添加显式强制转换:
int main() {
unsigned long int x=0;
/* unsigned long int * int */
x = 0x8000UL * 0x2;
/* unsigned long + unsigned int */
x = (unsigned long)0x8000 + 0x8000;
return 0;
}
另请参阅In a C expression where unsigned int and signed int are present, which type will be promoted to what type?进行一般性讨论。
答案 1 :(得分:1)
不清楚变量x应该是0x10000的方式。 x是unsigned long int
,但您为其指定的值为unsigned int
。如果在该平台上int
仅为16位,则0x8000 * 2
和0x8000 + 0x8000
均为0。
尝试使用0x8000L
(或更好的0x8000UL
)来创建长文字。