IEEE制定的浮点数格式
鉴于有人问到在C语言中float和double型态的储存格式的问题,所以我就在这边献丑一翻,讲讲我所了解的部份,如有任何错误,请各位大哥多多指教...
IEEE制定之浮点数格式说明:
float型态:用4个bytes储存,也就是32 bits.
各个bit的用途如下:
bit 31 23~30 0~22
┌───┬────┬───────┐
│正负号│ 指数 │ 底数 │
└───┴────┴───────┘
double型态:用8个bytes储存,也就是64 bits.
各个bit的用途如下:
bit 63 52~62 0~51
┌───┬────┬───────┐
│正负号│ 指数 │ 底数 │
└───┴────┴───────┘
<说明>正负号(sign): 1为负, 0为正.
指数(exponential):将底数乘上2的指数次方后就是原来的数.
须注意的是: float时,因有8 bits,所以能表示的有2的
256次方,但因为指数应可正可负,所以IEEE规定,此处算
出的次方须减去127才是真的指数,所以float的指数可从
-126到128.
同理, double型态有11 bits,算出的值须减去1023,所以
double的指数可从-1022到1024.
底数(mantissa):此部份格式实在难以用文字说明,
请参考下面的例子.
<特例> 0因为无法用任何2的次方表示,所以0的表示法就是
float : 00 00 00 00
double: 00 00 00 00 00 00 00 00
<范例>将17.625换算成float型态.
首先,先将17.625换算成2进位: 10001.101
(什么??你问我小数是怎么换的??好吧,就告诉你好了,因为
0.625 = 0.5 + 0.125 , 0.5即1/2 , 0.125即1/8 ,所以
0.625换算成2进位是0.101 ,如果你还没懂,请你再问别
人.当然,这里的数字是为了讲解方便才用这么完美的小数,
实际的小数部份,是用无限逼近出来的.)
再来将10001.101向右shift直到小数点前只剩一位(这一位
数当然是1),变成了1.0001101 x 2的4次方(因为向右移了
4位).此时,我们要的底数和指数就出来了:底数部份,因为小
数点前必为1,所以IEEE规定只记录小数点后的就好,所以此
题的底数为0001101 .指数部份实际为4,但在格式中须加上
127 ,固为131 ,即二进位的10000011.
综合上列各项, 17.625的float储存格式就是:
0 10000011 00011010000000000000000
转换成byte : 41 8D 00 00
另外,因为INTEL CPU是little endian的,所以
41 8D 00 00在记忆体中是按00 00 8D 41的顺序放的. (位址
由低到高)
以上的资料,都可以在Borland C++的IDE环境下,用watch的功能观察证
明出来.
鉴于有人问到在C语言中float和double型态的储存格式的问题,所以我就在这边献丑一翻,讲讲我所了解的部份,如有任何错误,请各位大哥多多指教...
IEEE制定之浮点数格式说明:
float型态:用4个bytes储存,也就是32 bits.
各个bit的用途如下:
bit 31 23~30 0~22
┌───┬────┬───────┐
│正负号│ 指数 │ 底数 │
└───┴────┴───────┘
double型态:用8个bytes储存,也就是64 bits.
各个bit的用途如下:
bit 63 52~62 0~51
┌───┬────┬───────┐
│正负号│ 指数 │ 底数 │
└───┴────┴───────┘
<说明>正负号(sign): 1为负, 0为正.
指数(exponential):将底数乘上2的指数次方后就是原来的数.
须注意的是: float时,因有8 bits,所以能表示的有2的
256次方,但因为指数应可正可负,所以IEEE规定,此处算
出的次方须减去127才是真的指数,所以float的指数可从
-126到128.
同理, double型态有11 bits,算出的值须减去1023,所以
double的指数可从-1022到1024.
底数(mantissa):此部份格式实在难以用文字说明,
请参考下面的例子.
<特例> 0因为无法用任何2的次方表示,所以0的表示法就是
float : 00 00 00 00
double: 00 00 00 00 00 00 00 00
<范例>将17.625换算成float型态.
首先,先将17.625换算成2进位: 10001.101
(什么??你问我小数是怎么换的??好吧,就告诉你好了,因为
0.625 = 0.5 + 0.125 , 0.5即1/2 , 0.125即1/8 ,所以
0.625换算成2进位是0.101 ,如果你还没懂,请你再问别
人.当然,这里的数字是为了讲解方便才用这么完美的小数,
实际的小数部份,是用无限逼近出来的.)
再来将10001.101向右shift直到小数点前只剩一位(这一位
数当然是1),变成了1.0001101 x 2的4次方(因为向右移了
4位).此时,我们要的底数和指数就出来了:底数部份,因为小
数点前必为1,所以IEEE规定只记录小数点后的就好,所以此
题的底数为0001101 .指数部份实际为4,但在格式中须加上
127 ,固为131 ,即二进位的10000011.
综合上列各项, 17.625的float储存格式就是:
0 10000011 00011010000000000000000
转换成byte : 41 8D 00 00
另外,因为INTEL CPU是little endian的,所以
41 8D 00 00在记忆体中是按00 00 8D 41的顺序放的. (位址
由低到高)
以上的资料,都可以在Borland C++的IDE环境下,用watch的功能观察证
明出来.