负数的二进制表示方法「建议收藏」

负数的二进制表示方法「建议收藏」负数的二进制表示方法假设有一个int类型的数,值为3,那么,我们知道它在计算机中表示为:00000000000000000000000000000011因为int类型的数占用4字节(32位),所以前面填了一堆0。在计算机中,负数以其正值的补码形式表达。什么叫补码呢?这得先从原码,反码说起。原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。比如

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

负数的二进制表示方法

假设有一个 int 类型的数,值为3,那么,我们知道它在计算机中表示为:

00000000 00000000 00000000 00000011

因为int类型的数占用4字节(32位),所以前面填了一堆0。

在计算机中,负数以其正值的补码形式表达。

什么叫补码呢?这得先从原码,反码说起。

原码:一个整数,按照绝对值大小转换成的二进制数,称为原码。

比如 00000000 00000000 00000000 00000011 是 3的 原码。

反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码。

取反操作指:1变0;0变1

比如:00000000 00000000 00000000 00000011的反码是11111111 11111111 11111111 11111100。 

补码:反码加1称为补码。

也就是说,要得到一个数的补码,先得到反码,然后将反码加上1,所得数称为补码。

比如:00000000 00000000 00000000 00000011 的反码是:11111111 11111111 11111111 11111100。

那么,补码为:

11111111 11111111 11111111 11111100 + 1 = 11111111 11111111 11111111 11111101

所以,-3 在计算机中表达为:11111111 11111111 11111111 11111101。转换为十六进制:0xFFFFFFFD。

整数-1在计算机中如何表示。

假设这也是一个int类型,那么:

1、先取1的原码:00000000 00000000 00000000 00000001

2、得反码:     11111111 11111111 11111111 11111110

3、得补码:     11111111 11111111 11111111 11111111


可见,-1在计算机里用二进制表达就是全1。16进制为:0xFFFFFF

负数用补码原因:

INT_MAX = 2147483647 ;

cout<<INT_MAX+1<<endl; //正确结果为-2147483648

UINT_MAX = 4294967295;

cout<<UINT_MAX+1<<endl; //正确结果为0

负数在计算机中如何表示?

举例来说,+8在计算机中表示为二进制的1000,那么-8怎么表示呢?

很容易想到,可以将一个二进制位(bit)专门规定为符号位,它等于0时就表示正数,等于1时就表示负数。比如,在8位机中,规定每个字节的最高位为符号位。那么,+8就是00001000,而-8则是10001000。

但是,随便找一本《计算机原理》,都会告诉你,实际上,计算机内部采用2的补码(Two’s Complement)表示负数。

什么是2的补码?

它是一种数值的转换方法,要分二步完成:

第一步,每一个二进制位都取相反值,0变成1,1变成0。比如,00001000的相反值就是11110111。

第二步,将上一步得到的值加1。11110111就变成11111000。

所以,00001000的2的补码就是11111000。也就是说,-8在计算机(8位机)中就是用11111000表示。

不知道你怎么看,反正我觉得很奇怪,为什么要采用这么麻烦的方式表示负数,更直觉的方式难道不好吗?

为什么要用2的补码

首先,要明确一点。计算机内部用什么方式表示负数,其实是无所谓的。只要能够保持一一对应的关系,就可以用任意方式表示负数。所以,既然可以任意选择,那么理应选择一种最方便的方式。

2的补码就是最方便的方式。它的便利体现在,所有的加法运算可以使用同一种电路完成

还是以-8作为例子。

假定有两种表示方法。一种是直觉表示法,即10001000;另一种是2的补码表示法,即1 1111000。请问哪一种表示法在加法运算中更方便?

随便写一个计算式,16 + (-8) = ?                     1 0001000 取反 1 1110111    加1    +1 = 1 1111000   

再取反  1 0000111  + 1  = 1 0001000 取反不不包括符号位两次取反得到原值                                                                         

正数的补码是其本身 负数的补码是符号位不变 其他位取反之后加1  

连着变换两次相当于没有做任何操作

16的二进制表示是 00010000,所以用直觉表示法,加法就要写成:                                                        

 00010000                                                                                                                                  
+10001000
---------
 10011000

可以看到,如果按照正常的加法规则,就会得到10011000的结果,转成十进制就是-24。显然,这是错误的答案。也就是说,在这种情况下,正常的加法规则不适用于正数与负数的加法,因此必须制定两套运算规则,一套用于正数加正数,还有一套用于正数加负数。从电路上说,就是必须为加法运算做两种电路。

现在,再来看2的补码表示法。

 00010000
+11111000
---------
100001000

可以看到,按照正常的加法规则,得到的结果是100001000。注意,这是一个9位的二进制数。我们已经假定这是一台8位机,因此最高的第9位是一个溢出位,会被自动舍去。所以,结果就变成了00001000,转成十进制正好是8,也就是16 + (-8) 的正确答案。这说明了,2的补码表示法可以将加法运算规则,扩展到整个整数集,从而用一套电路就可以实现全部整数的加法。

2的补码的本质及正确性

我们要看先一下模的概念

“模”是指一个计量系统的计数范围。如时钟等。计算机也可以看成一个计量机器,它也有一个计量范

  围,即都存在一个“模”。例如:

  时钟的计量范围是0~11,模=12。

  表示n位的计算机计量范围是0~2^(n)-1,模=2^(n)。

  “模”实质上是计量器产生“溢出”的量,它的值在计量器上表示不出来,计量器上只能表示出模的

  余数。任何有模的计量器,均可化减法为加法运算。

  例如: 假设当前时针指向10点,而准确时间是6点,调整时间可有以下两种拨法:

  你可以往回拨4个小时,也可以向前拨8个小时(12-10+6,在钟表系统里模是12)

  在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替

  对“模”而言,8和4互为补数。实际上以12模的系统中,11和1,10和2,9和3,7和5,6和6都有这个特

  性。共同的特点是两者相加等于模。

  对于计算机,其概念和方法完全一样。n位计算机,设n=8, 所能表示的最大数是11111111,若再

  加1称为100000000(9位),但因只有8位,最高位1自然丢失。又回了00000000,所以8位二进制系统的

  模为2^8。 在这样的系统中减法问题也可以化成加法问题,只需把减数用相应的补数表示就可以

  了。

       再次重申一下这句话:

      在以12模的系统中,加8和减4效果是一样的,因此凡是减4运算,都可以用加8来代替。      

      所以对于为10000 0000的8位系统来说,减去b和加上10000 0000-b是一个道理,而(10000 0000-b)是什么?恰好就是b的补码

补码怎么求,“取反加一” 这口诀怎么来的?

承认了8 – 5 = 8 + (-5的补码)这个事实后,我们来看-5的补码怎么求,“取反加一”怎么来的

其实看完了上面的模的问题,该问题的答案基本已经出来了

-5的补码是 10000 0000 – 5 = 1111 1111 + 1 -5 = (1111 1111 – 5) + 1

1111 1111减去一个数事实上就是在对这个数取反,后面那个是+1

两个小问题的解释:

(1)

32位系统里,int的最大值为01111111 11111111 11111111 11111111,加1之后为

10000000   00000000   00000000   00000000。这个数是什么?

首先这是个负数–>负数在计算器里都是补码形式存放–>这是个补码–>那么真值是?–> -2147483648(已知负数的补码求该负数,不会求的百度一下吧。。。)

(2)                                                                                                                                                                     再取反就得到原来的值

对于unsigned,最大值(32个1)加1后最前面的1自然丢失,剩下32个0,所以就是0。

结束。


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/234396.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 获取activexobject对象失败_js获取对象

    获取activexobject对象失败_js获取对象js

    2022年10月14日
  • 二叉树层序遍历实现

    二叉树层序遍历实现二叉树的层序遍历下图是一个简单的二叉树例图实现思路:1.创建一个队列用于二叉树的层序遍历。2.将二叉树根节点插入队列中。3.通过while循环遍历二叉树,直至遍历完整个二叉树后则结束循环。4.每次循环开始时先进行出队操作,若当前出队元素为null则证明已经完成层序遍历结束循环循环,若不为null则打印该节点的值,并判断该节点是否存在左右子树,若存在则依次插入队列中。图解上述二叉树的层序遍历过程依次进行图上操作直至最终队列为空时则层序遍历结束。实现代码如下:classTreeNod

  • PhalApi 1.4.2 经典封存版 – 码云

    PhalApi 1.4.2 经典封存版 – 码云

  • 【pycharm】解决pycharm无法在settings里安装库的问题

    【pycharm】解决pycharm无法在settings里安装库的问题本来想直接在pycharm的setting里安装库,但是安装的时候一直转圈圈,要么是太慢要么显示失败。发现用命令行可以解决这个问题。具体操作如下:打开命令行,输入下面语句(确保路径一致)。安装完成:刷新一下pycharm的setting中显示库的界面,可以看到已经更新了不少个库。搞定~~…

  • TLSF算法1:二级索引的计算

    TLSF算法1:二级索引的计算TLSF算法(一)分配中的位图计算一、什么是TLSF算法二,f的确定三、s的确定四、实验结果一、什么是TLSF算法在嵌入式系统中,内存需要在分配和释放时有一个确定的相应时间,才能进一步分析其实时任务的可调度性。因此TLSF算法是一个十分适用嵌入式领域的动态内存分配算法。在关于TLSf算法的经典文章中《TLSF:aNewDynamicMemoryAllocatorforReal-TimeSystems》详细介绍了TLSF算法相关知识。TLSF算法使用隔离匹配机制来实现良好匹配策略。基本的

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号