C++取反符号及原码反码补码

19 篇文章 2 订阅
5 篇文章 0 订阅

按位取反符号

这里说的取反符号指的是~而不是!
~会对数值进行取反操作。

例如,1的二进制表示为00000000 00000000 00000000 00000001。
~1则为11111111 11111111 11111111 11111110,即—— -2。

这里需要注意,实际上-2在计算机中的存储并非为11111111 11111111 11111111 11111110。

注:本文默认数值有32个二进制位。

这里涉及到原码反码和补码相关知识。

在介绍原码反码补码之前,我们需要了解一下机器码相关的知识。

机器码

一个数在计算机中的二进制表示形式, 叫做这个数的机器数。

机器数带符号,一般把二进制为的最高位定为其符号位,最高位为0是为非负数,为1是是负数。

例如2表示为00000000 00000000 00000000 00000010,
-3表示为10000000 00000000 00000000 00000011。

真值

机器码对应的真实数值称为真值。

例如机器码10000000 00000000 00000000 00000011 对应的真值为-3,而非2147483651。

原码、反码、补码

原码反码和补码是计算机存储一个数值的编码方式。
只有有符号数才有原码反反码和补码。
在C/C++中,(signed) char、(signed) short、(signed) int、(signed) long、(signed) long long都为有符号类型,
而unsigned char、unsigned short、unsigned int、unsigned long、unsigned long long都为无符号类型。无符号类型相比于相应的有符号类型,有大了约一倍的正数取值范围,但却无法表示负数。

例如:

unsigned int a = -1;
cout << a << endl;

输出为

4294967295

原码

原码就是符号位加上真值的绝对值。

例如:
1表示为00000000 00000000 00000000 00000001。
-1表示为10000000 00000000 00000000 00000001。

反码

非负数和负数的表示方法有所不同。

  • 非负数:反码与原码一样。
  • 负数:将该负数的原码,符号位保持不变,其余各位进行取反运算。

例如:
1 = 00000000   00000000   00000000   0000000 1 反 码 1 = 00000000\ 00000000\ 00000000\ 00000001_{反码} 1=00000000 00000000 00000000 00000001

− 1 = 11111111   11111111   11111111   1111111 0 反 码 -1 = 11111111\ 11111111\ 11111111\ 11111110_{反码} 1=11111111 11111111 11111111 11111110

在这里插入图片描述
如图所示。

补码

补码在负数与非负数的表示上也有不同。

  • 非负数:补码和原码一样。
  • 负数:补码等于反码+1。

例如:
-1的补码表示为:11111111 11111111 11111111 11111111。
如下图所示。
在这里插入图片描述
负数在计算机上是以补码的形式存储的。

C++位取反

~常用在条件判断中,例如:

if(~a) cout << "a != -1" << endl;

这个语句相当于:

if(a != -1) cout << "a != -1" << endl;

由上方补码的介绍我们可以得出,-1在计算机中以二进制的形式存储为11111111 11111111 11111111 11111111,即所有位都为1。

而按位取反运算,会将包括符号位在内的每一位进行取反操作,因此~-1的结果为00000000 00000000 00000000 00000000,即为0。

注:在C/C++的条件判断中,非零即为真。

补充

逻辑取反符号

!也是C/C++中的“取反符号”,但它的运算过程和按位取反符号~并不一样。

!更准确地说应该是逻辑取反符号,它的效果是将真变成假,将假变成真。

~则是按位进行的取反运算。

更快速地计算

如何快速的知道一个数的进行按位取反后的值是多少呢?
例如 ~5的值是多少呢?

除了按照其转换规则进行计算外,还有更加简便的方法得出其值。
在取值范围内,有
  a = − 1 − a ~a = -1 - a  a=1a

注意优先级

按位取反符号在C语言中的优先级为2,在C++中的优先级为3,与自增运算符同一个优先级,优先级较高,在复合运算时需要多加注意。

为什么会有补码

在计算机中,使对两个数实现加法非常简单,但将两个数进行减法运算却并不容易。
有因为
a − b = a + ( − b ) a - b = a + (-b) ab=a+(b)
所以可以考虑将减法变成加法进行计算。

但是使用原码进行计算,却也并不容易,需要让计算机辨别到最高位的符号位,这会使得计算变得繁琐,降低计算机的计算速度。

补码正是因此而生的,使用补码表示负数后,当两个数互为相反数,相加结果直接为0,不需要多考虑符号位之类的问题,也避免了繁琐的运算流程降低了计算机的计算效率。


原创不易,感谢支持!

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wingaso

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值