C++ 不要将有符号整数和无符号整数相加

有符号整数和无符号整数相加时,把负数转换成无符号数类似于直接给无符号数赋一个负值,结果等于这个负数加上无符号数的模。

unsigned int n = 300;
int m = -500;
cout << m + m << '\n';
cout << n + m << '\n';

输出:

-1000        // 正确
4294967096   // 错误

结果做个类型转换后,貌似是对的:

int nm = n + m; 

这样输出nm-200

当有符号的数值绝对值小于等于无符号的时候好像算的是对的(vs2015)。

unsigned int n = 300;
int m = -200;
cout << m + m << '\n';
cout << n + m << '\n';

输出:

-400
100
unsigned int n = 300;
int m = -300;
cout << m + m << '\n';
cout << n + m << '\n';

输出:

-600
0

当从无符号数中减去一个值时,不管这个值是不是无符号数,我们都必须确保结果不能是一个负值:

unsigned ul=42, u2=10;
std::cout<<ul-u2<< std::endl;//正确:输出 32
std::cout<<u2-ul<< std::endl;//正确:不过,结果是取模后的值 4294967264

输出:

32
4294967264

无符号数不会小于0这一事实同样关系到循环的写法。例如,在 1.4.1节的练习(第11页)中需要写一个循环,通过控制变量递减的方式把从10到0的数字降序输出。这个循环可能类似于下面的形式:

// 这个时对的
for(inti=10;i>=0;--i)
    std::cout<<i<< std::endl;

下面这种写法永远退不出循环:

//错误:变量u永远也不会小于0,循环条件一直成立
for(unsignedu=10;u>=0;--u)
   std::cout<<u<< std::endl;

所以,一定不要混用无符号整数和有符号整数,不能将负数赋值给无符号变量。

相乘,也是不对的。

unsigned a = 1;
int b = -1;
cout << a * b << '\n';

输出:

4294967295    // 不对,你可能期望的时 -1。将这个数强转成有符号,它就是 -1。




参考:《C++ Primer》 P34
posted @ 2024-09-11 14:06  double64  阅读(146)  评论(0)    收藏  举报