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