读书人

有符号和无符号数的乘法,两个不同的结

发布时间: 2012-03-23 12:06:21 作者: rapoo

有符号和无符号数的乘法,两个不同的结果,求解释
网上都说,如果一个无符号数和一个有符号数做运算,那么会按照无符号的法则,把有符号数当作无符号来做计算:
下面这个代码:

C/C++ code
int main(void){    char c1=0xFE;    char c2=0x02;    int s1=c1*c2;    unsigned int s2=c1*(unsigned char)c2;    unsigned int s3=(unsigned char)c1*c2;    printf("%d,%u,%u\n",s1,s2,s3);    return 0;}

结果是-4,4294967292,508
为什么s2和s3不一样? 都是用了强转成无符号数,然后两个无符号数在汇编那一层用imul来相乘啊。
这两个乘法的反汇编代码如下:
Assembly code
    unsigned int s2=c1*(unsigned char)c2;//signed:movsx   unsigned:movzx004134F4  movsx       eax,byte ptr [c1]  004134F8  movzx       ecx,byte ptr [c2]  004134FC  imul        eax,ecx  004134FF  mov         dword ptr [s2],eax     unsigned int s3=(unsigned char)c1*c2;00413505  movzx       eax,byte ptr [c1]  00413509  movsx       ecx,byte ptr [c2]  0041350D  imul        eax,ecx  00413510  mov         dword ptr [s3],eax  


只是movsx和movzx交换了位置.
为什么计算的结果不一样?

[解决办法]
s2中c1应该是先被转成了unsigned int了,而s3中c1是unsigned char
[解决办法]
楼上正解!
[解决办法]
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。

[解决办法]
S2中c1*(unsigned char)c2 也就是-2*2=-4 然后(unsigned int)-4 = 4294967292
S3中(unsigned char)c1=254 (unsigned char)c1*c2 = 508 (unsigned int)508 = 508


[解决办法]
这么多人解释了,怎么楼主还是不明白
unsigned int s2=c1*(unsigned char)c2;
因为c1是char,值为-2,转unsigned int 为0xffffffe
而(unsigned char)c1,先把c1转成(unsigned char)为253,转转unsigned int还是253

[解决办法]
探讨

引用:

S2中c1*(unsigned char)c2 也就是-2*2=-4 然后(unsigned int)-4 = 4294967292
S3中(unsigned char)c1=254 (unsigned char)c1*c2 = 508 (unsigned int)508 = 508


unsigned和signed相乘,会被当成……

读书人网 >C语言

热点推荐