8051 16位加法/乘法结果16位而不是32位

时间:2017-10-11 16:16:23

标签: c 16-bit integer-arithmetic integer-promotion

我有问题。在此程序中,变量x应设置为0x10000,但在两个操作中结果为0.

这不是主程序,而是查找错误原因的测试。我目前正在使用十六进制输入制作64位乘法器。我使用Keil和Proteus

进行了16位乘法运算
int main() {
    unsigned long int x = 0;
    x = 0x8000 * 0x2;
    x = 0x8000 + 0x8000;
    return 0;
}

2 个答案:

答案 0 :(得分:6)

文字0x8000的类型为 unsigned int 。在您的16位计算机上,int因此unsigned int的自然大小为16位,是C标准接受的最小值。整数提升规则表示较小的宽度类型被扩展为intunsigned int,但不再进一步(C11 n1570 6.3.1.1p2)

  

如果int可以表示原始类型的所有值(受宽度限制,对于位字段),则该值将转换为int;否则,它将转换为unsigned int。这些被称为整数促销。 58)所有其他类型由整数促销保持不变。

仅当其他操作数的排名更高时,操作数才会从intunsigned 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 * 20x8000 + 0x8000均为0。

尝试使用0x8000L(或更好的0x8000UL)来创建长文字。