精华内容
下载资源
问答
  • 主要介绍了C语言基础 原码、反码、补码和移码详解的相关资料,需要的朋友可以参考下
  • 在讨论之前,先说一下无符号数有符号数的概念,计算机的数均存放在寄存器中,通常称寄存器的位数为机器字长,所谓无符号数,即没有符号的数,在寄存器中的每一位均可用来存放数值,有符号数是首位不用来表示数值,...

    在讨论之前,先说一下无符号数和有符号数的概念,计算机的数均存放在寄存器中,通常称寄存器的位数为机器字长,所谓无符号数,即没有符号的数,在寄存器中的每一位均可用来存放数值,有符号数是首位不用来表示数值,而是用来表示正数或负数。另外再说一下机器数和真值的区别:把符号“数字化”的的数称为机器数,而把带“+”或“-”的数称为真值

    原码:

           

           当x=-0.1101时,[x]原=1-(-0.1101)=1.1101

    补码:



    码:



    移动码:


    移动码是用来比较数的大小

    正数的补码原码都是其本身,负数的补码是其原码除符号位按位取反加1,反码是其原码除符号位按位取反。

    展开全文
  • 文章目录一、概述1.进制转换2.无符号数及有符号数(1) 无符号数(2)有...反码(1)整数的反码(2)小数的反码(3)特性4.移码(1)整数的移码(2)特性5.总结三、浮点数1.浮点数的表示2.非规格化浮点数3.规格化...


    一、概述

    1.进制转换

    https://blog.csdn.net/sandalphon4869/article/details/88298591

    2.无符号数及有符号数

    (1) 无符号数

    没有符号位,则数中的每一位均用来表示数值。

    所以,8 位二进制无符号数所表示的数值范围是 0~255, 16 位无符号数的表示范围为 0~65535。

    (2)有符号数

    带有符号位表示正负,符号位放在有效数字的前面,这样就组成了有符号数。
    如4位有符号数范围是-7~7.

    3. 定点数与浮点数

    (1)定点数

    若约定小数点的位置固定不变,则称为定点数。

    有两种形式的定点数:定点整数(就是纯整数,小数点定在最低有效数值位之后)和定点小数(就是纯小数,小数点在最高有效数值位之前)。在这里插入图片描述

    (2)浮点数

    小数点位置浮动

    二、机器数(二进制数、有符号数)

    各种数值数据在计算机中表示的形式称为机器数。机器数对应的实际数值称数的真值。

    0.总结

    (1)数的特征

    符号位

    机器码01
    原码0正1负
    反码0正1负
    补码0正1负
    移码0负1正

    唯一零:补码(0000…0)、移码(1000…0)
    不唯一的零:原码(+0与-0,即0000…0与1000…0)、反码(0000…0与1111…1)

    (2)范围

    Something Help:

    • 1000: 2 4 − 1 = 2 3 = 8 2^{4-1}=2^3=8 241=23=8
    • 0111: 2 2 + 2 1 + 2 0 = 2 3 = 2 4 − 1 − 1 = 7 2^2+2^1+2^0=2^3=2^{4-1}-1=7 22+21+20=23=2411=7,也可以因为0111+1=1000,那么0111=1000-1= 2 3 − 1 = 7 2^3-1=7 231=7
    • 0.001: 2 − 3 = 0.125 2^{-3}=0.125 23=0.125
    • 0.111: 2 − 1 + 2 − 2 + 2 − 3 = 0.875 2^{-1}+2^{-2}+2^{-3}=0.875 21+22+23=0.875,也可以因为0.111+0.001=1.000,那么0.111=1.000-0.001= 1 − 2 − 3 = 0.875 1-2^{-3}=0.875 123=0.875

    原码 n 位(包括一位符号位):

    • 整数数值范围分别为:1111…1~0111…1,即 − ( 2 n − 1 - 1 ) ~ + ( 2 n − 1 - 1 ) -(2^{n-1}-1)~+(2^{n-1}-1) (2n11)(2n11)。0111…1是 ( 2 n − 1 - 1 ) (2^{n-1}-1) (2n11),最小负数是加个负号, − ( 2 n − 1 - 1 ) -(2^{n-1}-1) (2n11)
    • 纯小数所能表示的:1.111…1~0.111…1,即 − ( 1 − 2 − ( n − 1 ) ) ~ + ( 1 - 2 − ( n − 1 ) ) {-(1-2^{-(n-1)})~+(1-2^{-(n-1)}}) (12(n1))+(12(n1))。0.111…1是 1 − 2 − ( n − 1 ) 1-2^{-(n-1)} 12(n1),最小负数是加个负号, − ( 1 − 2 − ( n − 1 ) ) -(1-2^{-(n-1)}) (12(n1))

    补码 n 位(包括一位符号位):

    • 整数数值范围分别为:1000…0~0111…1,即 − 2 n − 1 ~ + ( 2 n − 1 − 1 ) -2^{n-1} ~ +( 2^{n-1}-1) 2n1+(2n11)。最大正整数同原码,而且负数可以取到下限 − 2 n − 1 -2^{n-1} 2n1
    • 小数数值范围分别为:1.000…0~0.111…1,即 − 1 ~ + ( 1 - 2 − ( n − 1 ) ) -1~+(1-2^{-(n-1)}) 1+(12(n1))。最大正小数同原码,而且负数可以取到下限-1。

    反码 n 位(包括一位符号位):
    正数的反码等于原码,负数的反码是对应正数原码的全部取反。那么表示范围同原码。

    • 整数数值范围分别为:1000…0~0111…1
    • 小数数值范围分别为:1.000…0~0.111…1

    移码 n 位(包括一位符号位):
    移码是补码的符号位取反,那么范围同补码。

    • 整数数值范围分别为:0000…0~1111…1
    • 小数数值范围分别为:0.000…0~1.111…1

    (3)自己的计算方式

    正整数

    [x]原= [x]反=[x]补

    [x]移=[x]补码的符号位取反

    负数

    因为求补运算

    • 正推
      真值→原码(符号位是1)
      真值→负数对应的正数的原码→补码(从右往左,第一个1左边全部取反)
      真值→负数对应的正数的原码→反码(包据符号位全部取反获得)
      真值→负数对应的正数的原码→补码(从右往左,第一个1左边全部取反)→移码

    • 反推
      原码→真值
      补码→负数对应的正数的原码(从右往左,第一个1左边全部取反)→真值
      反码→负数对应的正数的原码(包据符号位全部取反获得)→真值
      移码→补码→负数对应的正数的原码(从右往左,第一个1左边全部取反)→真值

    整数补位增

    正数:都是次高位补0
    如真值3(011)→00011(原码)→00011(补码)→00011(反码)
    移码(111)→(10011)

    负数:

    • 原码:负数次高位补0
    • 补码:负数次高位补1
    • 反码:负数次高位补1
    • 移码:负数次高位补1

    如:真值-3
    原码:111→10011
    补码:101→11101
    反码:100→11100
    移码:001→01101

    整数补位删

    正数:把符号位和符号位右边第一个1之间的0都删掉。
    如真值3→00011(原码)→00011(补码)→00011(反码)→(011)
    移码(10011)→(111)

    负数:

    • 原码:把符号位和符号位右边第一个1之间的0都删掉。(删去补的0)
    • 补码:把符号位和符号位右边第一个0之间的1都删掉。(删去补的1)
    • 反码:把符号位和符号位右边第一个0之间的1都删掉。(删去补的1)
    • 移码:把符号位和符号位右边第一个0之间的1都删掉。(删去补的1)

    如:真值-3
    原码:10011→111
    补码:11101→101
    反码:11100→100
    移码:01101→001

    特殊情况

    • 注意原码的+0和-0

    • 【求-8的的八位补码】
      8的原码(0000 1000)→-8的的八位补码(1111 1000)

    • 【1111 1000是补码,则对应真值是?】
      补码→正数的原码(0000 1000)→真值-8

    • 【求-8的的四位补码】
      8的原码(01000)→-8的的八位补码(11000)→补位删(1000)

    • 【1000是补码,则对应真值是?】
      补码→正数的原码(1000),出错
      补码→补位增(11000)→正数的原码(0 1000)→真值-8

    1.原码

    原码是机器数中最简单的一种表示形式。

    (1)整数的原码

    表示方法一:由真值得到

    在这里插入图片描述
    恰好位数的原码:

    • 先确定位数: ± 2 n − 1 \pm2^{n-1} ±2n1正数小于,负数大于
      3的表示: 3 < 2 2 = 2 3 − 1 3 < 2^2=2^{3-1} 3<22=231,所以用三位二进制表示。
      -3的表示: − 3 > − 2 2 = − 2 3 − 1 -3>-2^{2}=-2^{3-1} 3>22=231,所以用三位二进制表示。
      这个3位是恰好的位数,既体现了符号位,数字中又没有多余的0。

    • 再按公式得到的十进制数→二进制数
      如:3的表示: ( 3 ) D → ( 11 ) B → ( 011 ) 原 (3)_D \to (11)_B \to (011)_{原} (3)D(11)B(011),用三位二进制011表示(高位补一个零,0其实是符号位)。
      -3的表示: ( 2 3 − 1 − ( − 3 ) ) D → ( 7 ) D → ( 111 ) B → ( 111 ) 原 (2^{3-1}-(-3))_D→(7)_D \to (111)_B→(111)_{原} (231(3))D(7)D(111)B(111),用三位二进制111表示。

    • 若要指定位数:在次高位(相当于是符号位后面)补0.
      指定5位原码:

      • 正数:次高位补0。如[3]原=0跟00跟11=00011
      • 负数:次高位补0。如[-3]原=1跟00跟11=10011

    直接得到指定位数的原码:

    • 正数还得补零:3的5位原码: ( 3 ) D → ( 11 ) B → ( 011 ) 原 → ( 00011 ) 原 (3)_D \to (11)_B \to (011)_{原}→(00011)_{原} (3)D(11)B(011)(00011)
    • 负数直接得到:-3的5位原码: [ 2 5 − 1 − ( − 3 ) ] D → ( 19 ) D → ( 10011 ) 原 [2^{5-1}-(-3)]_D \to (19)_D \to (10011)_{原} [251(3)]D(19)D(10011)

    表示方式2:原码=[符号位][数值位],给定位数。

    符号位:0 表示正数。符号位为 1表示负数。
    数值位即将真值的绝对值转换成二进制数,不够的位数次高位补0(符号位后面)。

    指定5位原码:

    • 正数:高位补0。如[3]原=0跟00跟11=00011
    • 负数:高位补1。如[-3]原=1跟00跟11=10011

    PS:纯整数和纯小数的数值位的表示方法(十进制到二进制)同数电:https://blog.csdn.net/sandalphon4869/article/details/88298591#三、数制转换

    总结:指定位数

    不管正负,都是在符号位后面补0

    (2)小数的原码

    表示方法一:按整数原码的定义

    在这里插入图片描述
    在这里插入图片描述

    • 按公式得到的十进制数→二进制数
      如:
      X=0.46875的原码表示: ( 0.46875 ) D → ( 0.01111 ) B (0.46875)_D \to (0.01111)_B (0.46875)D(0.01111)B
      X=-0.46875的原码表示: ( 1 − ( − 0.46875 ) ) D = ( 1.46875 ) D → ( 1.01111 ) B (1-(-0.46875))_D=(1.46875)_D \to (1.01111)_B (1(0.46875))D=(1.46875)D(1.01111)B

    • 若要指定位数,在末位补0
      如:指定8位
      若 X=0.46875 ,[X]原 =0.0111100
      若 X=-0.46875,[X]原 =1.0111100

    表示方式2:原码=[符号位][数值位]

    符号位为 0 表示正数,为 1表示负数。
    数值位即真值的绝对值(后面的补零个数=位数-符号位的位数1个-真值位的位数)。

    如:

    • 若 X=0.46875 ,用包括符号位为 8 位的定点原码表示,则可表示为:[X]原 =0.0111100
    • 若 X=-0.46875,用包括符号位为 8 位的定点原码表示,则可表示为:[X]原 =1.0111100

    指定位数:

    不管正负,都是在末位补0.

    (3)特性

    零的问题:有两种表示形式+0和-0(符号位)

    以 8 位原码表示的 0 为:
    [+0]原=0.0000000 或[+0]原=00000000,
    [-0]原=1.0000000 或[-0]原=10000000
    可见[+0]原不等于[-0]原.

    范围

    原码 n 位(包括一位符号位):

    • 整数数值范围分别为: − ( 2 n − 1 - 1 ) ~ + ( 2 n − 1 - 1 ) -(2^{n-1}-1)~+(2^{n-1}-1) (2n11)(2n11)
    • 纯小数所能表示的: − ( 1 − 2 − ( n − 1 ) ) ~ 1 - 2 − ( n − 1 ) {-(1-2^{-(n-1)})~1-2^{-(n-1)} } (12(n1))12(n1)

    2.补码

    (1)整数补码

    在这里插入图片描述

    确定位数: ± 2 n − 1 \pm2^{n-1} ±2n1

    正数小于,负数大于等于。
    如:35的表示: 35 < 2 6 = 2 7 − 1 35 < 2^6=2^{7-1} 35<26=271,所以用七位二进制表示。
    -35的表示: − 35 ≥ − 2 6 = − 2 7 − 1 -35 \geq -2^{6}=-2^{7-1} 3526=271,所以用七位二进制表示。

    正整数的补码:同原码

    如:真值35的原码

    • 定义法: ( 35 ) D → ( 10   0011 ) B → ( 010   0011 ) 原 (35)_D \to (10\ 0011)B \to (010\ 0011)_{原} (35)D(10 0011)B(010 0011)
    • 格式法:0跟10 0011,所以010 0011

    若指定8位,次高位补0,则[35]原=0跟0跟10 0011=0010 0011。

    负整数的补码:

    如:-35的补码
    ①8位定义法表示: 2 8 + X = 256 + ( − 35 ) = ( 221 ) D → ( 11011101 ) B 2^{8}+X=256+(-35)=(221)_D \to (1101 1101)_B 28+X=256+(35)=(221)D(11011101)B,1101 1101即为所求。
    ②对应正数的8位原码表示,包括符号位在内各位取反,(获得-35的反码),再在最低位上加 1。
    ③负数的8位原码表示,不包括符号位各位取反,(获得-35的反码),再在最低位上加 1。
    ④对应正数的8位原码表示,从最低位逐位向高位找起,找到第一个1不变,以后各位1变0、0变1,包括符号位。

    若指定位数,负数次高位补1

    例子:-12的8位补码
    
    ①2^8-12=244=1111 0100
    
    ②-12对应正数12的原码(0000 1100)→所有位取反(1111 0011)→+1(1111 0100)
    
    ③-12对应负数-12的原码(1000 1100)→符号位不变,其他位取反(1111 0011)→+1(1111 0100)
    
    ④-12对应正数12的原码(0000 1100)→从右往左,第一个1左边全部取反→(1111 0100)
    

    (2)小数的补码

    在这里插入图片描述
    在这里插入图片描述

    正小数的补码:同正小数的原码

    若纯小数 X=0.46875 ,用包括符号位为 8 位的定点补码表示,则可表示为:[X]补 =0.0111100

    负小数的补码:同负整数的补码方法一样

    若纯小数 X=-0.46875 ,用包括符号位为 8 位的定点补码表示,则可表示为:[X]补 =1.1000100

    (3)特性

    求补运算【链接】

    https://blog.csdn.net/sandalphon4869/article/details/90614068#2_31

    简化加减法【链接】

    https://blog.csdn.net/sandalphon4869/article/details/90614068#3_55

    可以明显地看出大小

    当同正负时,补码本身表示二进制数,越大越大,越小越小。如1111(-1)比1000(-8)大。

    PS:移码则是不论同正负都是如此。

    范围

    通过上述说明,n 位补码表示的整数数值范围为: − 2 n − 1 到 2 n − 1 − 1 -2^{n-1} 到 2^{n-1}-1 2n12n11

    n 位补码表示的小数数值范围为: − 1 到 1 - 2 − n + 1 -1到1-2^{-n+1} 112n+1

    0 的表示是唯一的

    [+0]补 =0.0000000
    [-0]补 =2+(-0.0000000)=10.0000000-0.0000000=0.0000000
    显然[+0]补 =[-0]补=0.0000000,即补码中的“零”只有一种表示形式。

    变形码(双符号位)

    规则:采用两位表示符号,即 00 表示正号、11 表示负号。第一位符号位记作S2,第二位符号位记作S1。

    作用:一旦发生溢出,则两个符号位就一定不一致,利用判别两个符号位是否一致便可以判定是否发生了溢出。

    当模数为 4 时,形成了双符号位的补码,如 X=-0.1001,对(mod 22)而言。
    
    [X]补= 22 +X=100.0000 000-0.1001 000=11.0111 000
    

    算术左移、右移

    符号逻辑规则
    <<左移各二进位全部左移指定的位数,高位丢弃,低位补0(相当于 × 2 移 的 位 数 ×2^{移的位数} ×2
    >>右移各二进位全部右移指定的位数,低位丢弃,正数(次)高位补0,负数(次)高位补1(相当于 ÷ 2 移 的 位 数 \div 2^{移的位数} ÷2

    3.反码

    反码通常用来作为由原码求补码或者由补码求原码的中间过渡。

    (1)整数的反码

    在这里插入图片描述

    正整数的反码:同补码,同原码

    若 X=35,其 8 位反码表示为: [X]反 =0010 0011

    负整数的反码:

    ①负数对应的正数的原码:包据符号位全部取反获得。

    ②负数的原码:保持符号位不变,其余各位(对数值位)取反来获得

    例 5:
    
    若 X=-35,其8位反码表示为: [X]反 =1101 1100
    ①~(正整数的原码)=~(0010 0011)=1101 1100
    ②[1][~(负整数原码的数值位)]=[1][~(010 0011)]=1101 1100
    

    (2)小数的反码

    在这里插入图片描述

    (3)特性

    两种0 的表示

    在数值的反码表示中,0 同样有两种表示形式,用 8 位表示如下:
    [ + 0 ] 反 = 0.000   0000 = 0000   0000 [+0]反=0.000\ 0000=0000\ 0000 [0]=0.000 00000000 0000
    [ - 0 ] 反 = 1.111   1111 = 1111   1111 [-0]反=1.111\ 1111=1111\ 1111 [0]=1.111 11111111 1111

    负数反码与补码的关系

    从反码及补码的定义可以看到:

    • 整数:
      [ X ] 反 = 2 n − 1 + X [X]反 =2^{n}-1+X [X]=2n1X
      [ X ] 补 = 2 n + X [X]补 =2^n+X [X]=2nX
      可见, [ X ] 补 = [ X ] 反 + 1 [X]补 =[X]反 +1 [X]=[X]1

    • 小数:
      [ X ] 反 = 2 - 2 − n + 1 + X [X]反 =2-2^{-n+1}+X [X]=22n+1X
      [ X ] 补 = 2 + X [X]补 =2+X [X]=2X
      可见, [ X ] 补 = [ X ] 反 + 2 − n + 1 [X]补 =[X]反 +2^{-n+1} [X]=[X]2n+1

    进一步验证了前面的结论:只要在某数值的反码的最低位上加 1 即可获得该数值的补码。

    数值范围

    同原码:
    n 位反码表示的整数数值范围为: - ( 2 n − 1 - 1 ) 到 + ( 2 n − 1 - 1 ) -(2^{n-1}-1)到+(2^{n-1}-1) (2n11)(2n11)
    n 位反码表示的小数数值范围为: - ( 1 - 2 − n − 1 ) 到 + ( 1 - 2 − ( n − 1 ) ) -(1-2^{-n-1})到+(1-2^{-(n-1)}) (12n1)(12(n1))

    4.移码

    由于移码多用于浮点数中表示阶码,均为整数,只介绍定点整数的移码表示。

    (1)整数的移码

    在这里插入图片描述

    求出该数的补码表示,而后将符号位取反。

    8 位字长移码:
    
    X=35,[X]补 =0010 0011,[X]移=1010 0011。
    X=-35, [X]补 =1101 1101,[X]移=0101 1101。
    

    定义求

    8 位字长移码
    
    X=35,[X]移=2^(n-1)+X=163=1010 0011。
    X=-35,[X]移=2^(n-1)+X=93=0101 1101
    

    (2)特性

    移码的零

    移码表示中,0 有唯一的编码为 1000…0

    移码与补码的关系

    在这里插入图片描述

    只要将补码的符号位取反,则补码就转换成了相应的移码;同样,只要将移码的符号位取反,则移码就转换成了相应的补码。
    进而可以想到,只要字长相同,补码与移码所能表示的数值范围是相同的。

    移码码值的大小就反映了数值的大小

    正数移码的码值一定大于负数移码的码值。也就是说,大码值所表示的数值一定大于小码值所表示的数值

    5.题

    • 反推(难点原码-0和补码的最小负值)
      在这里插入图片描述
      答案:-0、-128、-127、0(注意原码是-0)
      先化成2进制,80H→1000 0000B。
      原码1000 0000→-0
      补码1000 0000→补位增(1 1000 0000)→正数的原码(0 1000 0000)→-128
      反码1000 0000→正数的原码(0111 1111)→-127
      移码1000 0000→补码0000 0000→0

    三、浮点数

    1.浮点数的表示

    如:–(53/512)

    • 表示方法1:
      在这里插入图片描述
      如, x = - 0.110101 × 2 − 11 x=-0.110101 \times 2^{-11} x=0.110101×211.(-11是二进制数,表示-3,2的-3次方)。式中

      • M 为尾数(负号直接写,是二进制小数),
      • E 为阶码(负号直接写,不是原码也不是补码什么的,而是二进制数),
      • R 是基数(或基值)。
    • 表示方法2:
      在这里插入图片描述
      ①阶码和尾数通常会用特殊的形式,如补码或者移码

      ②阶码E:用表示方法2,符号位就是阶符,数值位就是阶码。

      ③尾数M:用表示方法2,符号位就是数符,数值位就是尾数。

      ④阶码E通常为带符号的纯整数,尾数M为带符号的纯小数。

      如:
      浮点数字长为 16 位,其中阶码为 6 位(含一位阶符),尾数为 10 位(含一位数符),阶码用移码,尾数用补码的形式。
      在这里插入图片描述
      通常不画图,阶码和尾数中间留个空写出来就行: [ x ] 浮 = 011101 1.001011000 [x]浮=011101 \quad 1.001011000 [x]=0111011.001011000
      过程在下面。

    2.非规格化浮点数

    范围

    以通式 F=M×R^E为例,设浮点数的基值 R=2;阶码的数值位取 k 位,阶符 1 位且采用补码表示;尾数的数值位取 n 位,尾符 1 位,同样采用补码表示。

    当浮点数为非规格化数时,可先分别求出阶码和尾数的表示范围
    在这里插入图片描述

    3.规格化的浮点数

    (1)什么是规格化的浮点数

    就是将尾数的绝对值限定在一个规定的数值范围内。当基值R为 2 时,规格化浮点数尾数的绝对值|M|应再0.5和1之间。(负数的绝对值可以取到1,正数的绝对值可以取到0.5)

    尾数格式

    当尾数 M 用补码表示(n是尾数的数值位的位数,不包含符号位)

    • 当 M≥0 时,规格化尾数的形式必须为:
      M=0.1XX…X
      (即 0.5 ≤ 1 × 2 − 1 + X × 2 − 2 + . . . ≤ + ( 1 - 2 − n ) 0.5 \leq 1\times 2^{-1}+X\times 2^{-2}+...\leq+(1-2^{-n}) 0.51×21+X×22+...(12n),所以小数点后一位必须为1)
      (则尾数的最小正值为:+1/2 ,尾数的最大正值为: + ( 1 - 2 − n ) +(1-2^{-n}) (12n) 。)
    • 当 M<0 时,规格化尾数的形式必须为:
      M=1.0XX…X
      (求补可以得到它的正小数补码: 0.1 X ‾ X ‾ . . . X ‾ + 2 − n 0.1\overline{X}\overline{X}...\overline{X}+2^{-n} 0.1XX...X+2n,即 + ( 1 / 2 + 2 − n ) ≤ 1 × 2 − 1 + X ‾ × 2 − 2 + . . . + X ‾ × 2 − n + 2 − n ≤ 1 +(1/2+2^{-n}) \leq 1\times 2^{-1}+\overline{X}\times 2^{-2}+...+\overline{X}\times 2^{-n}+2^{-n} \leq 1 +(1/2+2n)1×21+X×22+...+X×2n+2n1,所以小数点后一位必须为0)
      (尾数的最小负值为:-1 ,尾数的最大负值为: − ( 1 / 2 + 2 − n ) -(1/2+2^{-n}) (1/2+2n) 。)

    (2)表示范围

    规格化尾数M的数值范围

    (n是尾数的数值位的位数,不包含符号位)
    尾数的最小正值为:+1/2 ,尾数的最大正值为: + ( 1 - 2 − n ) +(1-2^{-n}) (12n)
    尾数的最小负值为:-1 ,尾数的最大负值为: − ( 1 / 2 + 2 − n ) -(1/2+2^{-n}) (1/2+2n)
    总的来说, − 1 到 + ( 1 - 2 − n ) -1 到+(1-2^{-n}) 1(12n)

    阶码E所表示的数值范围

    与非规格化浮点数是一样的

    规格化浮点数的数值范围

    在这里插入图片描述
    在这里插入图片描述
    k是阶码的数值位的位数,n是尾数的数值位的位数。(都不包含符号位)
    表示范围 − 1 × 2 2 k − 1 到 ( 1 − 2 − n ) × 2 2 k − 1 -1\times 2^{2^k-1}到(1-2^{-n})\times 2^{2^k-1} 1×22k1(12n)×22k1

    例题

    某浮点数格式如下:7位阶码(包含一个符号位),9位尾数(包含一个符号位),若阶码用移码、尾数用补码表示,则浮点数的表示范围是:
    解析:将k=6,n=8代入最小负数和最大正数。
    − 2 63 到 ( 1 − 2 − 8 ) × 2 63 -2^{63} 到 (1-2^{-8})\times 2^{63} 263(128)×263

    (3)溢出

    溢出

    当浮点数阶码大于最大阶码时,称为“上溢”,此时机器停止运算,进行中断溢出处理;当浮点数阶码小于最小阶码时,称为“下溢”,此时“溢出”的数绝对值很小,通常将尾数各位强置为零,按机器零处理。

    4.规格化浮点数

    (1)规格化

    将非规格化数转换成规格化数的过程叫做规格化。

    当尾数不是规格化数时

    通过修改阶码并同时左右移尾数的办法,使其变成规格化数。

    对于基数不同的浮点数:左规和右规

    说白了,就是移动小数点位数,指数改变, 100 = 1 × 1 0 2 = 100 × 1 0 − 1 100=1 \times 10^2=100 \times 10^{-1} 100=1×102=100×101

    当基数R为 2 时,

    左规(向左规格化):尾数左移一位,相当于 × 2 1 \times 2^1 ×21,为保持不变则阶码减 1。

    右规(向右规格化):尾数右移一位,相当于 ÷ 2 1 \div 2^1 ÷21,为保持不变则阶码加 1。

    (2)例题

    例 6: 将十进制数 X=+13/128 写成二进制定点数和浮点数(尾数部分取 7 位,阶码部分取 7 位,阶符和数符各取 1 位,阶码采用移码,尾数用补码表示),分别写出该数的定点数和浮点数的表示形式。

    解:
    定点数真值表示: [X]B=0.0001 101
    定点编码表示:[X]原=[X]补=[X]反=0.0001 101

    规格化浮点数真值表示: X = 0.1101   000 × 2 − 11 X=0.1101\ 000×2^{-11} X=0.1101 000×211(左移3位,-11是二进制数即-3)
    规格化浮点编码表示形式如图所示:
    (阶码E-3的八位补码是1111 1101,移码是0111 1101,即阶符0,阶码111 1101)
    (尾数M0.1101 000的数符是0,尾数是1101 000)
    在这里插入图片描述

    例 7: 设浮点数字长为 16 位,其中阶码为 6 位(含一位阶符),尾数为 10 位(含一位数符),写出 X= –(53/512)对应的浮点规格化数阶码用移码,尾数用补码的形式。

    解: X = – ( 53 / 512 ) = - 0.0001   1010   1 = ( - 0.1101   0100   0 ) × 2 − 11 X= –(53/512)= -0.0001\ 1010\ 1= (-0.1101\ 0100\ 0)\times 2^{-11} X=(53/512)=0.0001 1010 1=0.1101 0100 0×211
    尾数的规格化补码形式为:1.0010 1100 0
    (方法是负数的补码方法4,用负数对应正数的原码从右往左,第一个1左边全部取反,所以负号就直接写着)
    阶码的移码表示为:-3→3原码:00 0011→-3补码:11 1101→-3移码:01 1101
    浮点表示形式如图所示:
    在这里插入图片描述

    四、其他的数据表示

    1.IEEE754

    在这里插入图片描述

    参数:

    • ( − 1 ) S (-1)^S (1)S:该浮点数的数符,当s为0时表示为正数,s为1时为负数
    • E:指数,用移码表示
    • ( b 0 。 b 1 b 2 b 3 . . . b p - 1 ) (b_0。b_1b_2b_3...b_{p-1}) b0b1b2b3...bp1:尾数,共P位,用原码表示。

    (1)单精度格式(32位)

    在这里插入图片描述
    s为数符为1位,阶码为8位(含1位阶符),f为尾数为23位。

    • 规格化时b0必须为1而且应隐去。
    • 阶码加01111111

    例8:现欲利用IEEE754标准将数176.0625表示为单精度浮点数。

    ①转化成正数:
    本来是正数自然没有影响,s=0,如果是负数,则之后讨论的都是它的正数,并且s=1。

    ②将该十进制来转换成二进制数:

    ( 176.0625 ) 10 = ( 10110000.0001 ) 2 (176.0625)_{10}=(1011 0000.0001)_2 176.06251010110000.00012

    ③对上面二进制数规格化:
    10110000.0001=1◆0110 0000 001×2^7
    这就保证了使b0为1,而且小数点在◆位置上。将b0去掉并扩展为单精度浮点数所规定的23位尾数:0110 0000 0010 0000 0000 000。

    ④现在, 再来求取阶码。
    阶数的真值+真值127,然后将结果转化为二进制(第一位不表示符号位)
    现指数为7即真值,而单精度浮点数规定指数的偏移量为127(请注意不是前面移码描述中所提到的128),即在指数7上加127,也就是e=7+127=134,从而得到则指数的移码表示为1000 0110。

    ⑤最后,将 ( 176.0625 ) 10 (176.0625)_{10} 176.062510表示为IEEE–754标准的单精度浮点数:
    0 10000110 01100000001000000000000

    (2)双精度格式(64位)

    在这里插入图片描述
    [ S : 1 个 ] [ E : 11 个 ] [ F : 52 个 ] [S:1个][E:11个][F:52个] [S1][E11][F52]

    2.奇偶校验码

    在这里插入图片描述

    (1)水平奇偶校验

    水平奇校验

    设数据 X = ( x 0 x 1 ⋅ ⋅ ⋅ x n − 1 ) X=(x_0x_1···x_{n-1}) X=(x0x1xn1)是一个 n 位字,若在其高位前增加 1 位奇校验位 c,
    保证在这里插入图片描述
    即,在这里插入图片描述

    例如:
    X=01010100,采用奇校验时,奇校验位 c 必须为 0,则加了奇校验的数据 X′=001010100。
    X=01010101,采用奇校验时,奇校验位 c 必须为 1,则加了奇校验的数据 X′=101010101。

    水平偶校验

    设数据 X = ( x 0 x 1 ⋅ ⋅ ⋅ x n − 1 ) X=(x_0x_1···x_{n-1}) X=(x0x1xn1)是一个 n 位字,若在其高位前增加 1 位奇校验位 c,
    保证在这里插入图片描述
    即,在这里插入图片描述

    例如:
    X=01010100,采用偶校验时,偶校验位 c 必须为 1,则加了奇校验的数据 X′=101010100。
    X=01010101,采用偶校验时,偶校验位 c 必须为 0,则加了奇校验的数据 X′=001010101。

    (2)垂直奇偶校验码

    在这里插入图片描述

    (2)水平垂直奇偶校验码

    在这里插入图片描述

    3.海明码

    https://blog.csdn.net/CeleCoCo/article/details/83507640

    4.循环冗余校验码(CRC 码)

    (1)模运算

    • 模 2 加法 按位加,不考虑进位:0+0=0,0+1=1,1+0=1,1+1=0.例如 1101+1011=0110。
    • 模 2 减法 按位减,不考虑借位:0-0=0,0-1=1,1-0=1,1-1=0.例如 1101-1011=0110。
      可见模 2 减法与模 2 加法运算结果相同,因此可用模 2 加法代替模 2 减法。
    • 模 2 乘法 按模 2 加求部分积之和,不考虑进位。例如 1010×1101=1110010。
      在这里插入图片描述
    • 模 2 除法 按模 2 减求部分余数,不借位,每求一位商应使部分余数减少一位。
      进商的规则是:余数首位为 1 商取 1,余数首位为 0 商取 0。当余数位数小于除数位数时即为最后余数。例如 10000÷101=101+01/101,商为 101,余数为 01。
      在这里插入图片描述

    上述这些法则,在后面求 CRC 校验码时将会用到。

    (2)CRC 码的编码

    步骤:

    1. 将有效信息 M(X) 化作数字表示:
      在这里插入图片描述
      如: M ( X ) = x 3 + x 2 = 1100 M(X)=x^3+x^2=1100 M(X)=x3+x2=1100

    2. 求余数的位数k:
      k = 生 成 多 项 式 G ( X ) 的 位 数 − 1 k=生成多项式G(X)的位数-1 k=G(X)1
      如:G(x)=1011,则k=4-1=3

    3. 将有效信息 M(X) 左移k位,低位补0
      如:1100左移3位,1100000

    4. 将左移后的有效信息被 G(X) 模2除,得到余数
      如:1100000与1011模2除,得到余数010

    5. 将左移后的有效信息和余数拼接
      如:1100000+010=1100010

    【例题】
    在这里插入图片描述

    (2)CRC 码的译码校验

    在这里插入图片描述

    将得到的CRC码除以生成多项式,如果余数是000,正确;否则,错误。

    展开全文
  • 二、原码反码补码和移码的基础概念计算方法 1.原码 2.反码 3.补码 4.移码 三、为何要使用原码反码,补码和移码 为何还会有反码和补码呢? 四、数值表示范围 五、原码反码补码再深入 一、机器数...

    目录

     

    一、机器数和真值

    1、机器数

    2、真值

    二、原码反码补码和移码的基础概念和计算方法

    1.原码

    2.反码

    3.补码

    4.移码

    三、为何要使用原码反码,补码和移码

    为何还会有反码和补码呢?

    四、数值表示范围

    五、原码反码补码再深入


    一、机器数和真值

    在学习原码反码,补码和移码之前需要先了解机器数和真值的概念。

     

    1、机器数

    一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机中用一个数的最高位存放符号正数为0负数为1。

    比如,十进制中的数+3,计算机字长为8位,转换成二进制就是0000 0011。如果是-3,就是1000 0011。

    那么,这里的0000 0011和1000 0011就是机器数。

     

    2、真值

     

    因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数1000 0011,其最高位1代表负,其真正数值是-3而不是形式值131(1000 0011转换成十进制等于131)。

    所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。例:0000 0001的真值=+000 0001=+1,1000 0001的真值=–000 0001=–1

     

    二、原码反码补码和移码的基础概念和计算方法

     

    在探求机器为何要使用补码之前让我们先了解原码反码,补码和移码的概念。对于一个数计算机要使用一定的编码方式进行存储。原码反码补码和移码是机器存储一个具体数字的编码方式。

     

    1.原码

     

    原码就是符号位加上真值的绝对值即用第一位表示符号其余位表示值。比如如果是8位二进制:

    [+1]原=0000 0001

    [-1]原=1000 0001

    第一位是符号位。因为第一位是符号位所以8位二进制数的取值范围就是:

    [1111 11110111 1111]==>[-127127]

     

    2.反码

     

    反码的表示方法是:

    1. 正数的反码是其本身;
    2. 负数的反码是在其原码的基础上符号位不变,其余各个位取反。

     

    [+]=[00000001]原 =[00000001]反 

    [-]=[0000001]原 =[1111110]反

     

    3.补码

     

    补码的表示方法是:

    1. 正数的补码就是其本身;
    2. 负数的补码是在其原码的基础上符号位不变其余各位取反最后+1(即在反码的基础上+1)。

     

    [+]=[00000001]原=[00000001]反=[00000001]补 

    [-]=[10000001]原=[11111110]反=[11111111]补

     

    4.移码

     

    移码是作用于阶码上的,移码的表示方法是:

    1. 正数的最高符号位用1表示;
    2. 负数的最高符号位用0表示;
    3. 其余原码位不变。

    [+]=[00000001]原 =[00000001]反=[00000001]补=[10000001]移 

    [-]=[10000001]原=[11111110]反=[11111111]补=[00000001]移

     

    三、为何要使用原码反码,补码和移码

    图1 数据的表示

     

                                                                                                图1 数据的表示

     

    计算机可以有三种编码方式表示一个数。对于正数,因为三种编码方式的结果都相同,所以不需要过多解释。

    [+1]=[00000001]原 =[00000001]反 =[00000001]补

    但是对于负数:

    [-1]=[10000001]原 =11111110]反 =[11111111]补

    可见原码反码和补码是完全不同的。

     

    为何还会有反码和补码呢?

     

    首先因为人脑可以知道第一位是符号位在计算的时候我们会根据符号位选择对真值区域的加减(真值的概念在本文最开头)。

    但是对于计算机,加减乘数已经是最基础的运算要设计的尽量简单。 计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂!于是人们想出了将符号位也参与运算的方法。

    根据运算法则减去一个正数等于加上一个负数即:1-1=1+(-1)=0所以机器可以只有加法而没有减法这样计算机运算的设计就更简单了。

    于是人们开始探索将符号位参与运算并且只保留加法的方法。首先来看原码:

    计算十进制的表达式:1-1=0

    为了解决原码做减法的问题出现了反码:

    1-1=1+(-1)=[0000 0001]原 +[1000 0001]原=[0000 0001]反 +[1111 1110]反 =[1111 1111]反 =[1000 0000]原 = -0

    发现用反码计算减法结果真值的部分是正确的,而唯一的问题其实就出现在"0"这个特殊的数值上。虽然人们理解上+0和-0是一样的但是0带符号是没有任何意义的。而且会有[0000 0000]原和[1000 0000]原两个编码表示0。

    于是补码的出现解决了0的符号以及两个编码的问题:

    1-1=1+(-1)=[0000 0001]原 +[1000 0001]原 =[0000 0001]补 +[1111 1111]补 =[0000 0000]补=[0000 0000]原

    这样0用[0000 0000]表示而以前出现问题的-0则不存在了。而且可以用[1000 0000]表示-128:

    (-1)+(-127)=[1000 0001]原 +[1111 1111]原 =[1111 1111]补 +[1000 0001]补 =[1000 0000]补

    -1-127的结果应该是-128在用补码运算的结果中[1000 0000]补 就是-128。但是注意因为实际上是使用以前的-0的补码来表示-128,所以-128并没有原码和反码表示(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原这是不正确的)。

    使用补码不仅仅修复了0的符号以及存在两个编码的问题而且还能够多表示一个最低数。这就是为什么8位二进制使用原码或反码表示的范围为[-127+127]而使用补码表示的范围为[-128 ,127]。

    因为机器使用补码所以对于编程中常用到的32位int类型可以表示范围是:[-231231-1]因为第一位表示的是符号位,而使用补码表示时又可以多保存一个最小值。

    移码是为了解决浮点数计算而来的,正数的最高符号位用0来表示,负数的最高位用1来表示就会混乱,颠倒了正常的思想观念,所以移码的最高符号位正好与原码、反码和补码的最高符号位相反,同时它进行相关操作也能得到正确的结果。

    1000 0001+0111 1111=1000 0000[移]

    最高符号位1代表正数,所以结果是0。

     

    四、数值表示范围

     

    数值表示范围公式

     

                                                                                 图2 数值表示范围公式

    上图可知,原码和反码的取值范围都是-127~127,可是补码是-128~127。

     

    为什么补码的取值范围比原码、反码的多一位呢?

     

    举例:

    +0=0000 0000[原]

    -0=1000 0000[原]

    可以看出不对等。

    +0=0000 0000[反]

    -0=1111 1111[反]

    可以看出不对等。

    +0=0000 0000[补]

    -0=0000 0000[补]

    可以看出相等,所以补码少占用了一个编码。所以它的取值范围要比原码和反码多一位。

     

    五、原码反码补码再深入

     

    计算机巧妙地把符号位参与运算并且将减法变成了加法背后蕴含了怎样的数学原理呢?

    将钟表想象成是一个1位的12进制数。如果当前时间是6点我希望将时间设置成4点需要怎么做呢?我们可以:

    1. 往回拨2个小时:6-2=4

    2. 往前拨10个小时:(6+10) mod 12=4

    3. 往前拨10+12=22个小时:(6+22) mod 12=4

    2、3方法中的mod是指取模操作16 mod 12=4,即用16除以12后的余数是4。

    所以钟表往回拨(减法)的结果可以用往前拨(加法)替代!

    现在的焦点就落在了如何用一个正数来替代一个负数。上面的例子我们能感觉出来一些端倪发现一些规律。但是数学是严谨的,不能靠感觉。

    首先介绍一个数学中相关的概念:同余。

     

    同余的概念

    两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余,记作a≡b(mod m),读作a与b关于模m同余。

    举例说明:

    4 mod 12 = 4

    16 mod 12 = 4

    28 mod 12 = 4

    所以4,16, 28关于模12同余。

     

    负数取模

    正数进行mod运算是很简单的,但是负数呢?

    下面是关于mod运算的数学定义:

    取模运算的数学定义

                                                                                               图 3 取模运算的数学定义

    上面是截图"取下界"符号找不到如何输入(word中粘贴过来后乱码)。下面是使用“L”和“J”替换上图的“取下界”符号:

    x mod y=x-y L x/y J

    上面公式的意思是:

    x mod y等于x减去y乘上x与y的商的下界。

    以-3 mod 2 举例:

    -3 mod 2

    =-3-2xL -3/2 J

    =-3-2x L-1.5 J

    =-3-2x(-2)

    =-3+4=1

    所以:

    (-2) mod 12=12-2=10

    (-4) mod 12=12-4=8

    (-5) mod 12=12-5=7

     

    开始证明

    再回到时钟的问题上:

    回拨2小时 = 前拨10小时

    回拨4小时 = 前拨8小时

    回拨5小时= 前拨7小时

    注意这里发现的规律!

    结合上面学到的同余的概念。实际上:

    (-2) mod 12=10

    10 mod 12=10

    -2与10是同余的。

    (-4) mod 12=8

    8 mod 12=8

    -4与8是同余的。

    距离成功越来越近了。要实现用正数替代负数只需要运用同余数的两个定理:

    反身性:

    a≡a (mod m)

    这个定理是很显而易见的。

    线性运算定理:

    如果a≡b(mod m),c≡d(mod m)那么:

    (1)a±c≡b±d(mod m)

    (2)a*c≡b*d(mod m)

    如果想看这个定理的证明请看:https://baike.baidu.com/item/%E5%90%8C%E4%BD%99%E5%AE%9A%E7%90%86/1212360?fromtitle=%E5%90%8C%E4%BD%99&fromid=1432545

    所以:

    7≡7(mod 12)

    (-2)≡10(mod 12)

    7-2≡7+10(mod 12)

    现在我们为一个负数找到了它的正数同余数。但是并不是7-2=7+10而是7-2≡7+10(mod 12)即计算结果的余数相等。

    接下来回到二进制的问题上看一下:2-1=1的问题.

    2-1=2+(-1)=[0000 0010]原 +[1000 0001]原=[0000 0010]反 +[1111 1110]反

    先到这一步-1的反码表示是1111 1110。如果这里将[1111 1110]认为是原码则[1111 1110]原=-126这里将符号位除去即认为是126。

    发现有如下规律:

    (-1) mod 127=126

    126 mod 127=126

    即:

    (-1) ≡ 126(mod 127)

    2-1 ≡ 2+126(mod 127)

    2-1 与 2+126的余数结果是相同的!而这个余数正式我们的期望的计算结果:2-1=1

    所以说一个数的反码实际上是这个数对于一个膜的同余数。而这个膜并不是我们的二进制而是所能表示的最大值!这就和钟表一样转了一圈后总能找到在可表示范围内的一个正确的数值!

    而2+126很显然相当于钟表转过了一轮而因为符号位是参与计算的正好和溢出的最高位形成正确的运算结果。

    既然反码可以将减法变成加法那么现在计算机使用的补码呢?为什么在反码的基础上加1还能得到正确的结果?

    2-1=2+(-1)=[0000 0010]原 +[1000 0001]原 =[0000 0010]补 +[1111 1111]补

    如果把[1111 1111]当成原码去除符号位, 则:

    [0111 1111]原 =127

    其实在反码的基础上+1只是相当于增加了模的值:

    (-1) mod 128=127

    127 mod 128=127

    2-1≡2+127(mod 128)

    此时表盘相当于每128个刻度转一轮。所以用补码表示的运算结果最小值和最大值应该是[-128,128]。

    但是由于0的特殊情况没有办法表示128,所以补码的取值范围是[-128 ,127]。

     

     

    展开全文
  • 原码、反码、补码和移码

    千次阅读 2018-11-13 10:44:08
    书中关于原码、反码、补码和移码的定义如下(n是机器字长): 原码: 反码: 补码: 移码: 一. 机器数真值 在学习原码, 反码和补码之前, 需要先了解机器数真值的概念. 1、机器数 一个...

    本篇文章讲解了计算机的原码, 反码和补码. 并且进行了深入探求了为何要使用反码和补码, 以及更进一步的论证了为何可以用反码, 补码的加法计算原码的减法.

    书中关于原码、反码、补码和移码的定义如下(n是机器字长):
    原码:

    反码:

     

    补码:

     

    移码:

     

    一. 机器数和真值

    在学习原码, 反码和补码之前, 需要先了解机器数和真值的概念.

    1、机器数

    一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1.

    比如,十进制中的数 +3 ,计算机字长为8位,转换成二进制就是00000011。如果是 -3 ,就是 10000011 。

    那么,这里的 00000011 和 10000011 就是机器数。

    2、真值

    因为第一位是符号位,所以机器数的形式值就不等于真正的数值。例如上面的有符号数 10000011,其最高位1代表负,其真正数值是 -3 而不是形式值131(10000011转换成十进制等于131)。所以,为区别起见,将带符号位的机器数对应的真正数值称为机器数的真值。

    例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1

    二. 原码, 反码, 补码的基础概念和计算方法.

    在探求为何机器要使用补码之前, 让我们先了解原码, 反码和补码的概念.对于一个数, 计算机要使用一定的编码方式进行存储. 原码, 反码, 补码是机器存储一个具体数字的编码方式.

    1. 原码

    原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:

    [+1]原 = 0000 0001
    [-1]原 = 1000 0001

    第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

    [1111 1111 , 0111 1111]

    [-127 , 127]

    原码是人脑最容易理解和计算的表示方式.

    2. 反码

    反码的表示方法是:

    正数的反码是其本身

    负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

    [+1] = [00000001]原 = [00000001]反
    [-1] = [10000001]原 = [11111110]反

    可见如果一个反码表示的是负数, 人脑无法直观的看出来它的数值. 通常要将其转换成原码再计算.

    3. 补码

    补码的表示方法是:

    正数的补码就是其本身

    负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

    例如:X=-101011 , [X]原= 10101011 ,[X]反=11010100,[X]补=11010101,[X]移=01010101

    对于负数, 补码表示方式也是人脑无法直观看出其数值的. 通常也需要转换成原码在计算其数值.

    4. 移码

    移码最简单了,不管正负数,只要将其补码的符号位取反即可。

    [+1] = [00000001]原 = [00000001]反 = [00000001]补
    [-1] = [10000001]原 = [11111110]反 = [11111111]补

    三. 为何要使用原码, 反码和补码

    在开始深入学习前, 我的学习建议是先"死记硬背"上面的原码, 反码和补码的表示方式以及计算方法.

    现在我们知道了计算机可以有三种编码方式表示一个数. 对于正数因为三种编码方式的结果都相同:

    [+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) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0

    发现用反码计算减法, 结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.

    于是补码的出现, 解决了0的符号以及两个编码的问题:

    1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原

    这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

    (-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补

    -1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)

    对于-128没有原码和反码可以这样理解,因为原码和反码的范围都是[-127,127],所以肯定不会存在-128的原码和反码,但是这里[1000 0000]补补算出来的原码值是[0000 0000]原是不正确,是因为在任何补码表示形式之后进行运算之后,得到的补码是不能够重新补算的吗?

    使用补码, 不仅仅修复了0的符号以及存在两个编码的问题, 而且还能够多表示一个最低数. 这就是为什么8位二进制, 使用原码或反码表示的范围为[-127, +127], 而使用补码表示的范围为[-128, 127].

    所以,可以得到这样一个结论,n bit的大小可以表示的数的范围为[-2的n-1次方,2的n-1次方-1]。可以这样理解为在原码的时候,首位是符号位,所以范围为[-2的n-1次方-1,2的n-1次方-1],但是转化为补码表示的时候,-0的补码被认为是-128,所以补码的时候是多出来一位的,表示的数的范围是[-2的n-1次方,2的n-1次方-1]。(减1是由于0的存在)

    补码出现的意义在于在计算机进行加减运算的时候,能够把两个补码表示形式的符号位也一起进行计算,得到的结果也是正确的补码表示形式,但是补码其实也是存在符号位的。首位为0的补码是个正数,首位为1的补码是个负数。

    因为机器使用补码, 所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

    四. 原码, 反码, 补码 再深入

    计算机巧妙地把符号位参与运算, 并且将减法变成了加法, 背后蕴含了怎样的数学原理呢?

    将钟表想象成是一个1位的12进制数. 如果当前时间是6点, 我希望将时间设置成4点, 需要怎么做呢?我们可以:

    1. 往回拨2个小时: 6 - 2 = 4
    1. 往前拨10个小时: (6 + 10) mod 12 = 4
    2. 往前拨10+12=22个小时: (6+22) mod 12 =4

    2,3方法中的mod是指取模操作, 16 mod 12 =4 即用16除以12后的余数是4.

    所以钟表往回拨(减法)的结果可以用往前拨(加法)替代!

    现在的焦点就落在了如何用一个正数, 来替代一个负数. 上面的例子我们能感觉出来一些端倪, 发现一些规律. 但是数学是严谨的. 不能靠感觉.

    首先介绍一个数学中相关的概念: 同余

    同余的概念

    两个整数a,b,若它们除以整数m所得的余数相等,则称a,b对于模m同余

    记作 a ≡ b (mod m)

    读作 a 与 b 关于模 m 同余。

    举例说明:

    4 mod 12 = 4
    16 mod 12 = 4

    28 mod 12 = 4

    所以4, 16, 28关于模 12 同余.

    负数取模

    正数进行mod运算是很简单的. 但是负数呢?

    下面是关于mod运算的数学定义:

     

    Paste_Image.png

    上面是截图, "取下界"符号找不到如何输入(word中粘贴过来后乱码). 下面是使用"L"和"J"替换上图的"取下界"符号:

    x mod y = x - y L x / y J

    上面公式的意思是:

    x mod y等于 x 减去 y 乘上 x与y的商的下界.

    以 -3 mod 2 举例:

    -3 mod 2
    = -3 - 2xL -3/2 J
    = -3 - 2xL-1.5J
    = -3 - 2x(-2)
    = -3 + 4 = 1

    所以:

    (-2) mod 12 = 12-2=10
    (-4) mod 12 = 12-4 = 8
    (-5) mod 12 = 12 - 5 = 7

    开始证明

    再回到时钟的问题上:

    回拨2小时 = 前拨10小时
    回拨4小时 = 前拨8小时
    回拨5小时= 前拨7小时

    注意, 这里发现的规律!

    结合上面学到的同余的概念.实际上:

    (-2) mod 12 = 10

    10 mod 12 = 10

    -2与10是同余的.

    (-4) mod 12 = 8
    8 mod 12 = 8

    -4与8是同余的.

    距离成功越来越近了. 要实现用正数替代负数, 只需要运用同余数的两个定理:

    反身性:

    a ≡ a (mod m)

    这个定理是很显而易见的.

    线性运算定理:

    如果a ≡ b (mod m),c ≡ d (mod m) 那么:
    (1)a ± c ≡ b ± d (mod m)
    (2)a * c ≡ b * d (mod m)

    如果想看这个定理的证明, 请看:http://baike.baidu.com/view/79282.htm

    所以:

    7 ≡ 7 (mod 12)
    (-2) ≡ 10 (mod 12)
    7 -2 ≡ 7 + 10 (mod 12)

    现在我们为一个负数, 找到了它的正数同余数. 但是并不是7-2 = 7+10, 而是 7 -2 ≡ 7 + 10 (mod 12) , 即计算结果的余数相等.

    接下来回到二进制的问题上, 看一下: 2-1=1的问题.

    2-1=2+(-1) = [0000 0010]原 + [1000 0001]原= [0000 0010]反 + [1111 1110]反

    先到这一步, -1的反码表示是1111 1110. 如果这里将[1111 1110]认为是原码, 则[1111 1110]原 = -126, 这里将符号位除去, 即认为是126.

    发现有如下规律:

    (-1) mod 127 = 126
    126 mod 127 = 126

    即:

    (-1) ≡ 126 (mod 127)
    2-1 ≡ 2+126 (mod 127)

    2-1 与 2+126的余数结果是相同的! 而这个余数, 正式我们的期望的计算结果: 2-1=1

    所以说一个数的反码, 实际上是这个数对于一个膜的同余数. 而这个膜并不是我们的二进制, 而是所能表示的最大值! 这就和钟表一样, 转了一圈后总能找到在可表示范围内的一个正确的数值!

    而2+126很显然相当于钟表转过了一轮, 而因为符号位是参与计算的, 正好和溢出的最高位形成正确的运算结果.

    既然反码可以将减法变成加法, 那么现在计算机使用的补码呢? 为什么在反码的基础上加1, 还能得到正确的结果?

    2-1=2+(-1) = [0000 0010]原 + [1000 0001]原 = [0000 0010]补 + [1111 1111]补

    如果把[1111 1111]当成原码, 去除符号位, 则:

    [0111 1111]原 = 127

    其实, 在反码的基础上+1, 只是相当于增加了膜的值:

    (-1) mod 128 = 127
    127 mod 128 = 127
    2-1 ≡ 2+127 (mod 128)

    此时, 表盘相当于每128个刻度转一轮. 所以用补码表示的运算结果最小值和最大值应该是[-128, 128].

    但是由于0的特殊情况, 没有办法表示128, 所以补码的取值范围是[-128, 127]


    链接:https://www.jianshu.com/p/55a8195291db
    链接:https://www.jianshu.com/p/129f9daae472
    來源:简书

    参考链接:http://www.ruanyifeng.com/blog/2009/08/twos_complement.html

     

    展开全文
  • 而在计算机的表达中有着机器数原码,反码,补码和移码等数据的编码表示方法。其中这些编码的方法称为码制。 一、机器数  各种数据在计算机中的表示的形式称为机器数,其特点是数的符号用0、1来表示。机器数并不...
  • 一、原码、反码、补码和移码的一般求法 码制 一般求法 原码 符号位用0表示正数,1表示负数,其余位不变。 反码 正数的反码与原码一样,负数的反码是对它的原码(除符号位外)各位取反。 补码 正数的补码...
  • 记忆转换原码、反码、补码和移码其实很简单,方便的认识四种码。
  • 一、真值机器数 介绍机器数的三种表示形式之前,先介绍一下真值机器数。 带+、-符号的数叫真值,把符号数字化得到的数称为机器数(1表示-,0表示+)。当机器数用原码表示时,整数的符号位数值位用逗号隔开,...
  • 概念 原码:如果机器字长为n,那么一个数的原码就是用一个n位的二进制数,其中最高位为符号位:正数为0,负数为1,剩下的n-1位表示概数的绝对值。... 正数的反码和补码都与原码相同。  负数的反码为对该数的...
  • 必知:正数的补码,原码,反码都相同,而且最高位符号位不会随其他数值位改变。 原码一个数的二进制数加上符号位就是他的原码 正数的原码0+二进制数值位 例如 3的二进制是011,他的原码是0011 负数的原码1+二进制...
  • [计算机组成原理]原码,补码,反码移码定义及相互转换规则 chapter 2 2.1 带符号数表示 2.1.1 原码(符号位 + 数值部分) 纯小数: ±0.Xn-1Xn-2…X1X0 (字长:n+1) 表示范围: -1 < x < 1 例:+0.1010110...
  • 对于反码和补码,要区别:已知[x补],求[-x补]的题目(连同符号位各位取反,末位加一)。 原码:1001101 反码:1,110010(除符号位以外,各位取反) 补码:1,110011(除符号位以外,各位取反,末位加一) ...
  • 原码,反码移码,补码之间的转换

    千次阅读 热门讨论 2019-08-25 21:50:18
    首先介绍一下什么是原码,反码移码以及补码。 原码:首先把一个数转成二进制的表达方式,然后把这个二进制的首位用0或1表示,0表示正数,1表示负数 反码、补码指的是:一种计算机中对数字的二进制定点表示方法。...
  • 原码、反码、补码、移码的作用?  在计算机内,机器数有无符号带符号数之分。无符号数表示正数,在机器数中没有符号位。位于无符号数,若约定小数点的位置在机器数的最低位之后,则是纯整数;若约定小数点的...
  • 关于原码、反码、补码和移码的定义如下 1:原码:      2:补码      3:反码      4:移码     上述公式很复杂,因此,可以总结出一些常见的规律: 原码 如果机器字长为n,那么一个数的原码就是用一...
  • 在学习原码,反码和补码之前 我们先来了解什么叫机器数真值 机器数: 一个数在计算机中的二进制表示形式,叫做这个数的机器数 机器数是带符号的 在计算机中用一个数的最高位存放符号 正数为0 负数为1 比如 十进制...
  • 计算方法是设计出来的,方法因为什么要这样设计的思维目的才是我们学习时的主线。 唐朔飞那本教材太高估我的智商,上来就是小数的,补码的全是抽象的计算,都不给几个例子(这,给初学者的教材?)…… 我们先用8...
  • 原码、反码、补码和移码其实很简单

    万次阅读 多人点赞 2017-05-09 22:52:48
    原文章地址:http://blog.csdn.net/liushuijinger/article/details/7429197最近在备战软考,复习到计算机组成原理的时候,看到书中关于原码、反码、补码和移码的定义如下(n是机器字长):原码:反码:补码:移码:看...
  • 另外还可以用移码来表示定点的整数,这个我们一会会展开在之后的讲解中,如果我们把真值记为X的话,那我们会用这种X加一个钟货号,然后右下角的标注园方不以这样的方式来表示,所对应的原码反码5码合1吗表示整数或者...
  • 反码 反码是原码转变为补码的一个中间状态 正数的反码与原码相同,负数的反码是符号位不变,数值位取反 如: +8:[x]反 = 0000 1000 -8:[x]反 = 1111 0111 整数可表示的范围:[-(2n-1),2n-1] +0.75:[x]反 = 0110 ...
  • 8位二进制数 整数无符号数的表示范围是:0~...整数反码的表示范围是:-127~+127 当x=+1110, [x]原=0,1110正数符号位是0 当x=-1110, [x]原=1,1110 负数符号位是1 当x=+1010,[x]补=0,1010 正数补码是本身 当x=-1101, [x]
  • 原码反码补码移码

    2020-03-29 21:47:02
    1)当真数为正数时,原码、反码和补码的表示形式相同,符号位为 “0”,数值位和真值相同; 2)当真值位负数时,原码、反码和补码的表示形式不相同,符号位为 “1”,并且对于数值部分:补码是原码的”取反加1“,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,794
精华内容 1,117
关键字:

反码和移码