补码与反码(附运算优先级)

2023-08-30 16:56:00

我们都知道在计算机存储的时候,有符号的数都会用最高位作为符号位。

参考:什么是原码、反码和补码

原码

就是正常的二进制数,把最高位改成符号位(0为正数,1为负数)。

正数计算不会有问题:

5+2:

0 0 0 0 0 1 0 1
+ 0 0 1 0
-----------------
0 0 0 0 0 1 1 1

=7

反码

正数的反码就是原码,负数的反码是把原码中除符号位以外的所有位(数值位)取反

为什么要引入反码呢?因为计算机中直接用原码加减只能解决正数加减,而带负数加减如果用原码就会出现很大的错误,如:

-56-1:原码

1 0 1 1 1 0 0 0
- 1
-----------------
1 0 1 1 0 1 1 1

=-55???

那如果我们用反码运算:

-56-1:反码

1 1 0 0 0 1 1 1
- 1
-----------------
1 1 0 0 0 1 1 0

=-57

没有任何问题。

补码

正数的补码是原码,负数的补码是反码加 1。

为什么要搞出一个奇奇怪怪的补码?

因为用反码做负数跨 0 运输也会错。

如:-3+5:反码

1 1 1 1 1 1 0 0
+ 0 1 0 1
-----------------
0 0 0 0 0 0 0 1

=1??

用补码:

1 1 1 1 1 1 0 1
+ 0 1 0 1
-----------------
0 0 0 0 0 0 1 0

正确。

不仅如此,如果用反码,0的表示就有了歧义,+0反码00000000,-0反码11111111,而且还浪费一个位置,但是用补码则不然。这也是为什么 int 的范围是 [2147483648,2147483647],负数可以多表示一个,而 2147483648 在 4 字节整型中并没有原码和反码,只有补码。

补码变原码:

  • 先减1再取反
  • 先取反再加1

个人认为第二个好记。

注:

进行位运算时用的都是补码,所以 OIer 们判断是不是 1 常用 ~p,如果是 -1 的话,结果就是0,也是因为 -1 的补码是全 1。

c++运算符优先级归纳

这里要千万注意一个细节,赋值运算符是从右到左进行运算的,这意味着我们如果边赋值边进行一些诸如操作符的运算时,可能会想当然的从左到右看,发现一点问题都没有,然鹅程序却和我们想象的不一样的运行的情况。所以最好把操作运算放在赋值外面做(压行怪的痛)。

本文作者:NBestの思潮

本文链接:https://www.cnblogs.com/NBest/p/17686996.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   NBest  阅读(79)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起