转载 IEEE 标准的 float 及 double 格式
Posted By: BlackCat (Paul) on board 'ee'
Date: Sat Apr 16 19:02:43 1994
Title: 转载 IEEE 标准的 float 及 double 格式
Posted By: Alexander (小饼)
Date : Sat Apr 16 17:13:00 1994
Title : IEEE 标准的 float 及 double 格式.
鉴于有人问到在 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 的功能观察证
明出来.
参考资料: Computer Organization (3rd ed.) p.304 ~ p.306
McGRAW-HILL Int'l
Authors: V. Carl Hamacher
Zvonko G. Vranesic
Safwat G. Zaky
终于打完了, 希望大家看得懂, 有问题也欢迎问. 这一篇也许可以建议 Board
Manager 复制到 EE board 的精华区内, 让我能名留青史 :-)
也希望老师们万一看到了, 念在苦劳的份上, 将我的成绩多加几分, 我的学号
是 8031xxx (啊!! 为了生命安危起见,我还是隐名埋姓好了 ....)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.