原码、反码、补码及负数取模

 

原码、反码、补码

作者:何新宇
链接:https://www.zhihu.com/question/20159860/answer/21113783
来源:知乎

符号位在补码运算里面是“模”,本身并不带符号的意义。

因为计算机将加法转换成加上一个“负数”,而负数又以补码的形式表现。补码比源码多一位,从这多出来的一位可以推断出原来数字的正负号,所以成为了符号位。

也就是说,不是特意留出一个符号位,用1和0来表示正负号。而是补码运算可以用最高位来表示正负,所以符号位诞生了。

那么为什么-128的补码是10000000?可以这样理解。-128是一个负数,所以它的补码是它的“模”减去它的绝对值,即:

100000000 - 10000000 = 10000000

那么为什么负数补码等于源码的反码加一呢?可以这样推导:

100000000 - 10000000 
= (11111111 + 00000001) - 10000000 
= 11111111 - 10000000 + 1 
= 01111111 + 1 //反码加一
= 10000000

作者:知乎用户
链接:https://www.zhihu.com/question/20159860/answer/71256667
来源:知乎

把左边第一位腾出位置,存放符号,正用0来表示,负用1来表示

但使用“原码”储存的方式,方便了看的人类,却苦了计算机

我们希望 (+1)和(-1)相加是0,但计算机只能算出0001+1001=1010 (-2)

另外一个问题,这里有一个(+0)和(-0)

为了解决“正负相加等于0”的问题,在“原码”的基础上,人们发明了“反码”

“反码”表示方式是用来处理负数的,符号位置不变,其余位置相反

当“原码”变成“反码”时,完美的解决了“正负相加等于0”的问题

过去的(+1)和(-1)相加,变成了0001+1101=1111,刚好反码表示方式中,1111象征-0

人们总是进益求精,历史遗留下来的问题—— 有两个零存在,+0 和 -0

我们希望只有一个0,所以发明了"补码",同样是针对"负数"做处理的

我们要处理"反码"中的"-0",当1111再补上一个1之后,变成了10000,丢掉最高位就是0000,刚好和左边正数的0,完美融合掉了

这样就解决了+0和-0同时存在的问题

另外"正负数相加等于0"的问题,同样得到满足

举例,3和(-3)相加,0011 + 1101 =10000,丢掉最高位,就是0000(0)

同样有失必有得,我们失去了(-0) , 收获了(-8)

所以对于编程中常用到的32位int类型, 可以表示范围是: -2^{31},2^{31}-1 

负数取模

详解负数取模运算 

https://blog.csdn.net/hk2291976/article/details/52775299

 -6 % 5这个运算,在python中的结果是4,但是在C/JAVA上的结果是-1

取模运算

所谓取模运算在数学上就是通过辗转相除法得到的余数,一般满足下面这个式子:

{\displaystyle {\begin{aligned}q\,&\in \mathbb {Z} \\a\,&=nq+r\\|r|\,&<|n|\end{aligned}}}

所以,r = a - nq,而q的计算历史上出了2个分支:

truncate

这派的思想很简单,就是截去小数部分。

r=a-n\operatorname {trunc} \left({\frac {a}{n}}\right)

比如3/2 = 1 , -3/2 = -1

floor

floor是Donald Knuth大神提出来的,它的意思是像下取整。这个就有意思了,因为在正数的时候和truncate一样,但是在负数的时候,向下取整就会出现和truncate不一样的结果。

r=a-n\left\lfloor {\frac {a}{n}}\right\rfloor

比如:3/2 = 1 -3/2 = -2

运用

C、JAVA使用的truncate的方法

-6 - (5*trunc(-6/5))= -6 - (5 * -1) = -1

python使用的floor的方式

-6 - (5*floor(-6/5))= -6 - (5 * -2) = 4

 其他参考

http://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值