
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 2024 年 4 月 19 日 via iPhone 因为后者 xx1 和 xx2 是负数. |
2 Hsinyao 2024 年 4 月 19 日 不要纠结这些语法,建议 objdump 看汇编 |
3 lindt99cocoa 2024 年 4 月 19 日 无符号数做零扩展,有符号数做符号扩展 |
4 ysc3839 2024 年 4 月 19 日 via Android 因为 1 没符号,转成有符号类型时也不带符号,2 有符号,转成有符号类型时就会带符号 |
5 cnbatch 2024 年 4 月 19 日 写成这样就容易懂了: 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 2024 年 4 月 20 日 via Android 第二个数值溢出,转成 int 型变成负数了 int 扩展成 long long ,高位按符号位扩展,所以仍是负数。 |