```c
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 进行强制类型转换了吗
举报· 72 次点击
登录 注册 站外分享
6 条回复  
chingyat 小成 2024-4-19 19:41:29
因为后者 xx1 和 xx2 是负数.
Hsinyao 小成 2024-4-19 19:47:30
不要纠结这些语法,建议 objdump 看汇编
lindt99cocoa 小成 2024-4-19 20:00:46
无符号数做零扩展,有符号数做符号扩展
ysc3839 小成 2024-4-19 20:02:36
因为 1 没符号,转成有符号类型时也不带符号,2 有符号,转成有符号类型时就会带符号
cnbatch 初学 2024-4-19 20:03:08
写成这样就容易懂了:

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
iceheart 小成 2024-4-20 14:32:11
第二个数值溢出,转成 int 型变成负数了
int 扩展成 long long ,高位按符号位扩展,所以仍是负数。
返回顶部