小数的二进制表示,阶码

在机器中表示一个浮点数时需要给出指数,这个指数用整数形式表示,这个整数叫做阶码,阶码指明了小数点在数据中的位置。

中文名  阶码     外文名 exponent
阶码:对于任意一个二进制数N,可用N=S×2P表示,其中S为尾数,P为阶码,2为阶码的底,P、S都用二进制数表示,S表示N的全部有效数字,P指明小数点的位置。当阶码为固定值时,数的这种表示法称为定点表示,这样的数称为“ 定点数”;当阶码为可变时,数的这种表示法称为 浮点表示,这样的数称为“ 浮点数”,这在前面已有介绍。

通常 定点数有两种表示法,均设P=0,小数点是隐含的,若数值部分为n位:
当S为纯 整数时,此时 定点数只能表示整数,所能表示的N范围是(2n-1)≥N≥-(2n-1);当S为 纯小数时,此时定点数只能表示小数,所能表示的N范围是(1-2-n)≥N≥-(1-2-n)。
实际数值不一定都是纯整数或 纯小数,运算前可选择比例因子,使所有原始数据化成纯小数或纯整数,运算后再用比例因子恢复成实际值。

BCD码

总述

通常,我们习惯用 十进制数表示数据,但计算机是用 二进制数来表示数据的,这就需要进行数值进制之间的转换。我们把每位 十进制数转换二进制数的编码,简称为BCD码(BinaryCodedDecimal)。BCD编码具有 二进制数的形式以满足 数字系统的要求,又具有 十进制数的特点。在某些情况下,计算机也可以对这种形式的数直接进行运算。
它是一种数字压缩存储编码,一个字节有8位,而数字0到9最多只需要使用4位,如果用一个字节来存储一个数字相对就会有一定的浪费,尤其是在传输过程中,由此人们就想出了压缩的办法,就是BCD编码。
BCD编码将一个字节的8位拆分成高4位和低4位两个部分,也就是说一个字节能存储两个数字。所以BCD的编码过程就是将数字压缩的过程,将两个字节的数字压缩成一个字节。反之,解码就是把一个字节的数字拆分为两个数字单独存放(大部分的处理都是按字节处理的)。

移码

表示浮点数时还常用一种称为移码的码制。浮点数的阶码表示指数大小,有正有负,为避开阶码的符号,对每个阶码都加上一个正的常数(称偏移常数),使能表示的所有阶码都为正整数,变成“偏移”了的阶码,又称“增码”。移码的值不小于0,这样阶码总为0,可以取消,浮点数小数点的实际位置由移码减去偏移常数来决定。
一个实数可表示成一个 纯小数与一个 乘幂之积。如 [1]  ;-0.0010011=-0.10011×2^-10(10在这里也是二进制);-110001101=-0.110001101×2^1001(1001同样为二进制)。
一个任意 实数,在计算机内部可以用指数(为整数)和 尾数(为 纯小数)来表示,用指数和尾数表示实数的方法称为 浮点表示法。
浮点数的长度可以是32位、64位甚至更长,分阶码和 尾数两部分。阶码位数越多,可表示的数的范围越大;尾数越多,所表示的数的精度越高。“ 移码”用来表示浮点型 小数的阶码。对于 正数,符号位为“1”,其余位不变,如+1110001的阶码为11110001;对于 负数,符号位为“0”,其余位取反,最后加“1”,如–1110001的阶码为00001111。
移码补码的关系是符号位互为 反码,例如:X=+1011时,[X]移=11011,[X]补=01011;X=–1011时,[X]移=00101,[X]补=10101。
注意:对 移码运算的结果需要加以修正,修正量为2n,即对结果的符号位取反后才是移码形式的正确结果。 移码表示中,0有唯一的编码——1000…00,当出现000…00时(表示–2n),属于浮点数下溢。

转载 http://blog.163.com/yql_bl/blog/static/847851692008112013117685/

目前C/C++编译器标准都遵照IEEE制定的浮点数表示法来进行float,double运算。这种结构是一种科学计数法,用符号、指数和尾数来表示,底数定为2——即把一个浮点数表示为尾数乘以2的指数次方再添上符号。下面是具体的规格:
            
符号位     阶码      尾数     长度
float           1          8        23      32
double          1         11        52      64

 

以下通过几个例子讲解浮点数如何转换为二进制数

例一:

已知:double类型38414.4

求:其对应的二进制表示。

分析:double类型共计64位,折合8字节。由最高到最低位分别是第636261……0位:
    
最高位63位是符号位,1表示该数为负,0表示该数为正;
    62-52
位,一共11位是指数位;
    51-0
位,一共52位是尾数位。

    
步骤:按照IEEE浮点数表示法,下面先把38414.4转换为十六进制数。
     
把整数部和小数部分开处理:整数部直接化十六进制:960E。小数的处理:
0.4=0.5*0+0.25*1+0.125*1+0.0625*0+……
    
实际上这永远算不完!这就是著名的浮点数精度问题。所以直到加上前面的整数部分算够53位就行了。隐藏位技术:最高位的1不写入内存(最终保留下来的还是52位)。
    
如果你够耐心,手工算到53位那么因该是:38414.4(10)=1001011000001110.
0110011001100110011001100110011001100(2)

科学记数法为:1.001011000001110 0110011001100110011001100110011001100,右移了15位,所以指数为15。或者可以如下理解:

1.001011000001110 0110011001100110011001100110011001100×2^15
    
于是来看阶码,按IEEE标准一共11位,可以表示范围是-1024 ~ 1023。因为指数可以为负,为了便于计算,规定都先加上1023(2^10-1),在这里,阶码:15+1023=1038。二进制表示为:100 00001110
    
符号位:因为38414.4为正对应 0
    
合在一起(注:尾数二进制最高位的1不要):
01000000 11100010 11000001 110
01100  11001100  11001100  11001100  11001100

 

例二:

已知:整数3490593(16进制表示为0x354321)

求:其对应的浮点数3490593.0的二进制表示。 

解法如下:

先求出整数3490593的二进制表示:

 H:    3     5    4    3    2     1   (十六进制表示)

 B:   0011  0101 0100 0011 0010  0001 (二进制表示)

        │←─────  21────→│

 

即: 

               1.1010101000011001000012×221

可见,从左算起第一个121位,我们将这21为作为浮点数的小数表示,单精度浮点数float由符号位1位,指数域位k=8位,小数域位(尾数)n=23位构成,因此对上面得到的21位小数位我们还需要补上20,得到浮点数的小数域表示为:

         1 0101 0100 0011 0010 0001 00

 

float类型的偏置量Bias=2k-1-1=28-1-1=127,但还要补上刚才因为右移作为小数部分的21位,因此偏置量为127+21=148,就是IEEE浮点数表示标准:

                          V = (-1)s×M×2E

                    E = e-Bias

中的e,此前计算Bias=127,刚好验证了E=148-127=21

 

148转为二进制表示为10010100,加上符号位0,最后得到二进制浮点数表示1001010010101010000110010000100,其16进制表示为:

 H:     4        A       5          5         0         C         8        4  

 B:  0100   1010   0101    0101   0000   1100  1000   0100

                    |←────      21        ─────→   |

     1|←─8   ─→||←─────       23       ─────→ |

 

这就是浮点数3490593.0(0x4A550C84)的二进制表示。

 

例三:

0.5的二进制形式是0.1

它用浮点数的形式写出来是如下格式

 

0                01111110                 00000000000000000000000


符号位           阶码                       小数位

正数符号位为0,负数符号位为1

阶码是以2为底的指数

小数位表示小数点后面的数字


下面我们来分析一下0.5是如何写成0 01111110 00000000000000000000000


首先0.5是正数所以符号位为0

再来看阶码部分,0.5的二进制数是0.1,0.11.0*2^(-1),所以我们总结出来:

要把二进制数变成(1.f)*2^(exponent)的形式,其中exponent是指数

而由于阶码有正负之分所以阶码=127+exponent;

即阶码=127+(-1)=126 01111110

余下的小数位为二进制小数点后面的数字,00000000000000000000000


由以上分析得0.5的浮点数存储形式为0 01111110 00000000000000000000000  

注:如果只有小数部分,那么需要右移小数点. 比如右移3位才能放到第一个1的后面, 阶码就是127-3=124.

例四   (20.59375)10 =(10100.10011 2

首先分别将整数和分数部分转换成二进制数:

20.59375
10100.10011

然后移动小数点,使其在第12位之间

10100.10011
1.010010011×2^4   e4

于是得到:

S
0 E4127131 M010010011

最后得到32位浮点数的二进制存储格式为:

0100 1001 1010 0100 1100 0000 0000 0000
(41A4C000)16

 

 

例五:
-12.5转为单精度二进制表示
12.5:
1.
整数部分12,二进制为1100; 小数部分0.5, 二进制是.1,先把他们连起来,从第一个1数起取24位(后面补0):
1100.10000000000000000000
这部分是有效数字。(把小数点前后两部分连起来再取掉头前的1,就是尾数)
2.
把小数点移到第一个1的后面,需要左移3位(1.10010000000000000000000*2^3, 加上偏移量127127+3=130,二进制是10000010,这是阶码。
3. -12.5
是负数,所以符号位是1。把符号位,阶码和尾数连起来。注意,尾数的第一位总是1,所以规定不存这一位的1,只取后23位:
1 10000010 10010000000000000000000
把这32位按8位一节整理一下,得:
11000001 01001000 00000000 00000000
就是十六进制的 C1480000.

例六:

2.025675
1.
整数部分2,二进制为10; 小数部分0.025675, 二进制是.0000011010010010101001,先把他们连起来,从第一个1数起取24位(后面补0):
10.0000011010010010101001
这部分是有效数字。把小数点前后两部分连起来再取掉头前的1,就是尾数: 00000011010010010101001
2.
把小数点移到第一个1的后面,左移了1, 加上偏移量127127+1=128,二进制是10000000,这是阶码。
3. 2.025675
是正数,所以符号位是0。把符号位,阶码和尾数连起来:
0 10000000 00000011010010010101001
把这32位按8位一节整理一下,得:
01000000 00000001 10100100 10101001
就是十六进制的 4001A4A9. 


例七:
(
逆向求十进制整数)一个浮点二进制数手工转换成十进制数的例子:
假设浮点二进制数是 1011 1101 0100 0000 0000 0000 0000 0000
1823位分成三段:
1 01111010 10000000000000000000000
最后一段是尾数。前面加上"1.", 就是 1.10000000000000000000000
下面确定小数点位置。由
E = e-Bias阶码E01111010,加上00000101才是01111111127),
所以他减去127的偏移量得e=-5。(或者化成十进制得122122-127=-5)。
因此尾数1.10(后面的0不写了)是小数点右移5位的结果。要复原它就要左移5位小数点,得0.0000110, 即十进制的0.046875
最后是符号:1代表负数,所以最后的结果是 -0.046875

注意:其他机器的浮点数表示方法可能与此不同. 不能任意移植

 

再看一例(类似例七)

比如:53004d3e

二进制表示为:

01010011000000000100110100111110

按照1个符号    8个指数          23个小数位划分

0              10100110         00000000100110100111110

正确的结果转出来应该是551051722752.0

该怎么算?

好,我们根据IEEE的浮点数表示规则划分,得到这个浮点数的小数位是:

 00000000100110100111110

那么它的二进制表示就应该是:

1.000000001001101001111102 × 239

这是怎么来的呢? 别急,听我慢慢道来。
标准化公式中的M要求在规格化的情况下,取值范围1<M<(2-ε)

正因为如此,我们才需要对原始的整数二进制表示做偏移,偏移多少呢?偏移2E
这个“E”怎么算?上面的239怎么得来的呢?浮点数表示中的8位指数为就是告诉这个的。我们知道:
E = e-Bias
那么根据指数位:

101001102=>16610
e=166,由此算出E=e-Bias=166-127=39,就是说将整数二进制表示转为标准的浮点数二进制表示的时候需要将小数点左移39位,好,我们现在把它还原得到整数的二进制表示:

1 00000000100110100111110 0000000000000000

1│←───── 23─────→│← 16─→│

23+16=39
,后面接着就是小数点了。
拿出计算器,输入二进制数1000000001001101001111100000000000000000
转为十进制数,不正是:551051722752么!

通过这例六例七,介绍了将整数二进制表示转浮点数二进制表示的逆过程,还是希望大家不但能掌握转化的方法,更要理解转化的基本原理。

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值