C++ | 负数比0大?

文章分析了C++编程中负数与unsigned类型比较时的转换机制,指出在类型不匹配时,编译器会自动转换数据类型以保证比较的正确性。同时讨论了不同类型之间的转换规则,如char和short转换至int,以及int和long/double的转换情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ | 负数比0大?

现象

在 for 的判断语句中,对区间进行遍历,得到的区间并非自己预想的区间:

uint32_t end_index = j * num_per_thread;
uint32_t start_index = (j + 1 ) * num_per_thread - 1;

for (int k = start_index; k >= end_index; --k) {
   std::cout << "  k: " << k << ", end_index: " << end_index
          << ", start_index: " << start_index << ", k >= end_index: " 
          << std::boolalpha << (k >= end_index) << std::endl;
}

实际屏幕输出

分析

for 中的 k 类型为 int , k >= end_index这句,判断左边是int类型,判断右边是 unsigned int 类型, 有符号和无符号进行比较的时候,会统一转换为无符号数进行比较,所以当负数和无符号比较时,负数会转换为无符号的数,当待比较的无符号数是0的时候,等式恒成立。

上述代码,在int 和 unsigned int 比较的时候,将左侧k 转换为 unsigned int 了,所以即便k是负数,转换为无符号后仍然符合。

修改代码需要将 start_index 和 end_index 转换为有符号的类型。

剖析

如果运算符两边的运算数类型不同,编译器会先将较低级类型转换为较高级类型,最终两边均为相同的类型,再进行比较。

本质上, 各种数据类型会全部转换为字节最高的数据类型进行运算,转换按数据长度增加的方向进行,以保证精度不降低。

编译器都可以自动进行数据类型转换,表达式所得值的类型为其中字节最高的数据类型。

赋值运算

所以常见的赋值运算,包括直接赋值、函数返回值、函数参数输入等,也存在两边数据类型不同的问题。

如果左右两边数据类型不同,编译器会自动将右侧数据类型转换为左侧数据类型,然后进行赋值。

因此如果左侧类型的等级大于右侧的,编译器会将右边数据类型转换为左边变量的类型,然后赋值,这样不会丢失数据精度;

如果左边数据类型等级小于右边的,编译器同样会转换,但是数据会丢失精度。

自动数据类型转换可以进行所有类型之间的转换。

类型提升

标准有符号整数类型的转换级别关系为:
long long int > long int > int > short int > signed char
char short转换

char转换成 int

unsigned char转换成 int

short转换成 int

如果short的字节长度小于int的字节长度 unsigned short转换成 int ; 如果short的字节长度等于int的字节长度, unsigned short转换成 unsigned int

int long double 转换
  1. 如果int的字节长度小于long的字节长度

类型等级由高到低依次为:long double、double、float、 unsigned long long、long long、unsigned long、long、unsigned int、int

  1. 如果int的字节长度等于long的字节长度

类型等级由高到低依次为:long double、double、float、unsigned long long、long long、unsigned long、unsigned int、long、int

double ←── float 高
↑
longunsignedint ←── char,short

无符号的数据还有很多,很容易被忽略,包括sizeof()strlen()、STL中的size()函数等等


>>>>> 欢迎关注公众号【三戒纪元】 <<<<<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值