浮点数在计算机中的表示和存储方式
根据IEEE标准,浮点数是通过科学计数法来存储的,比如120.5用十进制的科学计数法来表示就是1.205*102.但是计算机中所有数据都是用二进制存储的,所以得先转换为二进制数,即1.1110001*26.
浮点数在计算机中的存储分为三个部分:
1. 符号位(sign):float和double符号位均为1位,0代表正数,1代表负数
2. 指数位(exponent):存储科学计数法中的指数部分,采用移位存储
3. 尾数位(Mantissa, fraction):存储科学计数法中的尾数部分
根据IEEE 754标准,单精度float类型使用32比特(4节)存储,其中1位表示符号,8位表示指数,23位表示尾数;双精度double类型使用64比特(8节)存储,1位符号位,11位指数位,52位尾数位。
float存储示例
以数字6.5为例,看一下这个数字是怎么存储在float
变量中的:
-
-
- 先来看整数部分,模2求余可以得到二进制表示为110。
- 再来看小数部分,乘2取整可以得到二进制表示为.1(如果你不知道怎样求小数的二进制,请主动搜索一下)。
- 拼接在一起得到110.1然后写成类似于科学计数法的样子,得到1.101 x 2 2
- 从上面的公式中可以知道符号为正,尾数是101,指数是2。
- 符号为正,那么第一位填0,指数是2,加上偏移量127等于129,二进制表示为10000001,填到2-9位,剩下的尾数101填到尾数位上即可。
S E E E E E E E E F F F F F F F F F F F F F F F F F F F F F F 0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -
内存中二进制数01000000 11010000 00000000 00000000表示的就是浮点数6.5
浮点数的指数位为什么要用移码表示阶码?(移位阶码请看移位操作符)
移码(又叫增码或偏置码)通常用于表示浮点数的阶码,其表示形式与补码相似,只是其符号位用“1”表示正数,用“0”表示负数,数值部分与补码相同。简单来说, 移码就是在原码的基础上加上一个偏移量。
首先,E为一个无符号整数(unsigned int) 这意味着,如果E为8位,它的取值范围为0~255;但是,E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;比如,2e10的E 是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。
然后,指数E从内存中取出还可以再分成三种情况:
E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127,得到真实值,再将有效数字M前加上第一位的1。
比如: 0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表达式为:
0 01111110 00000000000000000000000
E全为0
这时,浮点数的指数E等于1-127,即为真实值, 有效数字F不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
E全为1
这时,如果有效数字F全为0,表示±无穷大正负取决于符号位s;
问什么8位阶码的偏置为127 ?
首先,这是IEEE标准规定的,我们必须执行。 其次,我来解释下为什么IEEE标准中,8位阶码的偏置为127。
1、8位移码的取值范围为0~255(00000000~11111111),但在浮点数的阶码中,00000000与11111111被保留用作特殊情况,所以阶码可用范围只有1~254,总共有254个值。
2、8位有符号数取值范围为-128~+127(10000000~01111111),这里的二进制用补码表示,其中特别规定补码10000000没有原码,为-128的补码,总共有256个值。
3、如果采用偏置128,在表达+127时会产生上溢(移码11111111被保留),所以在阶码中偏置为(128-1),与此同时,在表达-127时会产生下溢(移码00000000被保留),所以阶码中去掉-127与-128,取值范围为-126~127,总共254个值。
float范围
明白了上面的原理就可求float类型的范围了,找到所能表示的最大值,然后将符号为置为1变成负数就是最小值,要想表示的值最大肯定是尾数最大并且指数最大,
那么可以得到尾数为 0.1111111 11111111 11111111,指数为 11111111,但是指数全为1时有其特殊用途,所以指数最大为 11111110,指数减去127得到127,
所以最大的数字就是1.1111111 1111111 11111111 x 2127 ,这个值为 340282346638528859811704183484516925440,通常表示成 3.4028235E38,那么float的范围就出来了:
[-3.4028235E38, 3.4028235E38] 有效数7个。
Pingback:变量,常量和数据类型和格式说明 – IC知识库