补码为什么能比原码多表示一个数(为什么补码的表示范围多一个)
8712023-08-24
大家好,感谢邀请,今天来为大家分享一下补码为什么能比原码多表示一个数的问题,以及和为什么用补码的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!
本文目录
这里给大家找来最详细和形象的解释。
我们知道了计算机可以有三种编码方式表示一个数.对于正数因为三种编码方式的结果都相同:
[+1]=[00000001]原=[00000001]反=[00000001]补
所以不需要过多解释.但是对于负数:
[-1]=[10000001]原=[11111110]反=[11111111]补
可见原码,反码和补码是完全不同的.既然原码才是被人脑直接识别并用于计算表示方式,为何还会
有反码和补码呢?
首先,因为人脑可以知道第一位是符号位,在计算的时候我们会根据符号位,选择对真值区域的加减.
(真值的概念在本文最开头).但是对于计算机,加减乘数已经是最基础的运算,要设计的尽量简单.
计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂!于是人们想出了将符号位也参与
运算的方法.我们知道,根据运算法则减去一个正数等于加上一个负数,即:1-1=1+(-1)=0,
所以机器可以只有加法而没有减法,这样计算机运算的设计就更简单了.
于是人们开始探索将符号位参与运算,并且只保留加法的方法.首先来看原码:
计算十进制的表达式:1-1=0
1-1=1+(-1)=[00000001]原+[10000001]原=[10000010]原=-2
如果用原码表示,让符号位也参与计算,显然对于减法来说,结果是不正确的.这也就是为何计算机内
部不使用原码表示一个数.
为了解决原码做减法的问题,出现了反码:
计算十进制的表达式:1-1=0
1-1=1+(-1)=[00000001]原+[10000001]原=[00000001]反+[11111110]反=[1111
1111]反=[10000000]原=-0
发现用反码计算减法,结果的真值部分是正确的.而唯一的问题其实就出现在"0"这个特殊的数值上.
虽然人们理解上+0和-0是一样的,但是0带符号是没有任何意义的.而且会有[00000000]原和[1000
0000]原两个编码表示0.
于是补码的出现,解决了0的符号以及两个编码的问题:
1-1=1+(-1)=[00000001]原+[10000001]原=[00000001]补+[11111111]补=[0000
0000]补=[00000000]原
这样0用[00000000]表示,而以前出现问题的-0则不存在了.而且可以用[10000000]表示-128:
(-1)+(-127)=[10000001]原+[11111111]原=[11111111]补+[10000001]补=[1000
0000]补
-1-127的结果应该是-128,在用补码运算的结果中,[10000000]补就是-128.但是注意因为实际上
是使用以前的-0的补码来表示-128,所以-128并没有原码和反码表示.(对-128的补码表示[10000000]
补算出来的原码是[00000000]原,这是不正确的)
使用补码,不仅仅修复了0的符号以及存在两个编码的问题,而且还能够多表示一个最低数.这就是为
什么8位二进制,使用原码或反码表示的范围为[-127,+127],而使用补码表示的范围为[-128,127].
因为机器使用补码,所以对于编程中常用到的32位int类型,可以表示范围是:[-231,231-1]因为第
一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.
十进制数在计算机内存中都以二进制补码的形式存在,主要是方便计算机计算。
在补码表示中0的补码表示是唯一的。[+1]补=[-1]补因此在补码表示中,就多出一个编码10000000把10000000的最高位既看做符号位又看做数值位,其值为-128原码表示中,10000000=[-0]原所以补码的表示范围就扩展一个。
所谓溢出是指数据的大小超出了编码的表数范同围。例如字长为8,补码的表数范围是-128D(10000000B)至+127D(01111111B)。现有两数求和127+1。按补码运算为01111111+00000001=10000000补码10000000B的真值为-128D。而127+1的正确结果应该是+128,超出了表数范围,溢出了。
关于本次补码为什么能比原码多表示一个数和为什么用补码的问题分享到这里就结束了,如果解决了您的问题,我们非常高兴。