unsigned int x1 = 0xaeb1c2aa;
unsigned int x2 = 0xaeb1c2aa;
long long r_whole = (signed long long)x1 * (signed long long)x2;
printf("r_whole = %lld\n",r_whole);
输出的结果是无符号乘法的结果:
r_whole = 8590088583138384100
而下面的程序
unsigned int x1 = 0xaeb1c2aa;
unsigned int x2 = 0xaeb1c2aa;
int xx1 = x1;
int xx2 = x2;
long long r_whole = (signed long long)xx1 * (signed long long)xx2;
printf("r_whole = %lld\n",r_whole);
输出的事有符号乘法的结果:
r_whole = 1860719719092984036
第一段程序里我不是对 x1 进行强制类型转换了吗
1
chingyat 225 天前 via iPhone
因为后者 xx1 和 xx2 是负数.
|
2
Hsinyao 225 天前
不要纠结这些语法,建议 objdump 看汇编
|
3
lindt99cocoa 225 天前 1
无符号数做零扩展,有符号数做符号扩展
|
4
ysc3839 225 天前 via Android
因为 1 没符号,转成有符号类型时也不带符号,2 有符号,转成有符号类型时就会带符号
|
5
cnbatch 225 天前
写成这样就容易懂了:
uint32_t x1 = 0xaeb1c2aa; // 2930885290 uint32_t x2 = 0xaeb1c2aa; int64_t var1 = x1; int64_t var2 = x2; long long r_whole = var1 * var2; x1 和 x2 强制转换成 signed long long 的时候,实际上就相当于 int64_t var1 = x1; 有符号 long long 能够容纳的范围足够大,大到可以完整“吞下”整个 0xaeb1c2aa |
6
iceheart 225 天前 via Android
第二个数值溢出,转成 int 型变成负数了
int 扩展成 long long ,高位按符号位扩展,所以仍是负数。 |