有符号数与无符号数运算的注意事项

Aki 发布于 2022-12-18 236 次阅读


(1)无符号数赋值给相同位数的有符号数基本上不会出现太大的问题,只需要保证有符号数的最大正数范围包含无符号数的最大范围就行。

size_t = 100;    // size_t = unsigned long long
int64_t - size_t // int64_t = long long

由于这两个64位的数值范围大到超乎天际,有符号64位范围是9223372036854775807,无符号是它的两倍,即使有符号的正数范围不包含无符号数的范围,一般也不会出现问题,除非有什么程序能够用到这么大的数值吧。。。。。。。

相反如果使用32位的有符号数来接受一个64位的无符号数,可能会出现问题,因为32位最大正数值是21亿,这个数值相对较小,容易出现问题。。。

size_t x = 2800000000;
int a = x;

上面的代码会发生正数溢出,结果a变成了负数!!!在实际中要尽量避免这种情况!!!

(2)有符号数赋值给无符号数时,当有符号数是大于等于0的数时没多大的问题,小于0时就有问题。

int a = 100;
unsigned int b = a;  //没什么问题
unsigned int c = -100;  //有大问题

在计算机中,整数都是以补码的形式计算的,-100的补码为其绝对值的补码形式表达,也就是 
00000000 00000000 00000000 01100100  100原码
11111111 11111111 11111111 10011011  100反码,所有二进制位取反,符号位也要取反!!
11111111 11111111 11111111 10011100  100补码,最低位+1

-100的补码也就是 11111111 11111111 11111111 10011100,0xffffff9c
当转换为无符号数时,解释的方式就变化了。即变成了 2^0*0 + 2^1*0 + 2^2*1 + .......
最终是一个很大的整数。。。。。。

(3)有符号数和无符号数运算时,有符号数会转换成无符号数进行运算,这也说明了无符号数的运算优先级大于有符号数。

unsigned int a = 100;
int b = -120;
cout << a + b << endl;

上面代码得不到正确的结果!!!!要尽量避免!!!