【C++】int类型转换为unsigned int类型

int类型强制转换为unsigned int时发生了什么?


前言

关注到这个问题是因为发现了一点有趣的事情,若将-1与(unsigned int)1比较会出现如下情况:

#include<iostream>
using namespace std;
int main()
{
	if (-1 < (unsigned int)1)
		cout << "-1小于(unsigned int)1为真" << endl;
	else cout << "-1小于(unsigned int)1为假" << endl;
}
//程序运行打印输出为:
//-1小于(unsigned int)1为假

程序运行打印输出为:
-1小于(unsigned int)1为假
若将-1 < (unsigned int)1作为if的判定条件,竟然会出现 “-1 < 1为False” 的结果,这是问什么呢?


1、数据的存储方式

要想知道上述例子中到底发生了什么,首先要知道数据在机器中是如何存储的。机器中实际存储的是原始数据的补码,因为补码方便进行数学运算,这里就会涉及到三个概念: 原码,反码,补码。下面的例子中,假设某台机器的int和unsigned int都占用4个字节,即32位。

  • 原码:正数的原码为其二进制表示;负数的原码为其绝对值的二进制表示,并将最高位置为1,表示其符号。
  • 反码:正数的反码与原码相同;负数的反码为其原码除符号位外,其他位按位取反。
  • 补码:正数的补码与原码相同;负数的补码为其反码+1。

示例:
3的原码:0000 0000 0000 0000 0000 0000 0000 0011
3的反码:0000 0000 0000 0000 0000 0000 0000 0011
3的补码:0000 0000 0000 0000 0000 0000 0000 0011
-3的原码:1000 0000 0000 0000 0000 0000 0000 0011
-3的反码:1111 1111 1111 1111 1111 1111 1111 1100
-3的补码:1111 1111 1111 1111 1111 1111 1111 1101

1.1 存储int型

在存储int型数据时,按照原始数据的补码存储。由于最高位是符号位,因此int所能表示数据的范围应为 -2^31 ~ 2^31-1 。例如:
存储int型1时,记录的为:0000 0000 0000 0000 0000 0000 0000 0001
存储int型-1时,记录的为:1111 1111 1111 1111 1111 1111 1111 1111

1.2 存储unsigned int型

在存储unsigned int型数据时,按照原始数据的补码存储,unsigned所能表示的范围为 0 ~ 2^32-1。因为无符号数不可能是负数,所以其补码也就是其原码。例如:
存储unsigned int型1时,记录的为:0000 0000 0000 0000 0000 0000 0000 0001

2、int型转换为unsigned int型

int型转换为unsigned int型其实就是把int型的31位和表示符号的最高位,一起看作是unsigned int型的32位一并读取,例如:
int型1:0000 0000 0000 0000 0000 0000 0000 0001,按unsigned的32位读法仍然为1
int型-1:1111 1111 1111 1111 1111 1111 1111 1111,按unsigned的32位读法为 2^32-1 = 4294967295
正数转换为unsigned时,数值与原来相等;负数转换为unsigned时,数值会发生变化。

#include<iostream>
using namespace std;
int main()
{
	cout << (unsigned int)1 << endl;
	cout << (unsigned int)-1 << endl;
}

打印输出结果为:
1
4294967295
程序的运行结果与预期一致。

3、int型与unsigned int型进行比较

回到前言的那个例子,为什么-1 < (unsigned int)1是False?我们要清楚C++在比较int和unsigned int时都做了什么。我们知道,不同类型的数据是无法直接进行比较的,在比较int和unsigned时,会先把int隐式类型转换为unsigned int,再将两个unsigned进行比较。这就解释了我们最初遇到的情况:-1 < (unsigned int)1是False,int型的-1首先被转换成unsigned型的4294967295,而语句“4294967295 < 1”当然是False。

结束语

在做 if 条件判断时,我们要尽可能避免int型变量与unsigned int型变量直接作比较的情况,可以减少一些类似于“ -1 <1 is False”这种“离奇”的事情发生。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值