汇编网首页登录博客注册
abob的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
学习动态

[2009-04-09 15:44] 关于IEEE标准的float类型

近日看到显卡支持2byte的近似float类型,称作half。于是上网搜了些资料,研究了一下float类型,是IEEE标准的4bytes单精度类型,从高位到低位分别表示: 阶符(S1),阶码(E8),尾数(M23)。  32位的浮点数中,S:浮点数的符号位,1 位,0表示正数,1表示负数。M:尾数,23位,用小数表示,小数点放在尾数域的最前面。E:阶码,8 位阶符采用隐含方式,即采用移码方式来表示正负指数。移码方法对两个指数大小的比较和对阶操作都比较方便,因为阶码域值大者其指数值也大。采用这种方式时,将浮点数的指数真值e 变成阶码E 时,应将指数 e 加上一个固定的偏移值127(01111111),即 E=e+127. 

一个规格化的32位浮点数x的真值可表示为 

         x=(-1)s×(1.M)×2E-127     e=E-127     

  一个规格化的64位浮点数x的真值为 

        x=(-1)s×(1.M)×2E-1023    e=E-1023       

64位double的数据为:阶符(S1),阶码(E11),尾数(M52)。  为提高数据的表示精度,当尾数的值不为0 时,其绝对值应≥0.5,即尾数域的最高有效位应为1,否则以修改阶码同时左右移小数点的办法,使其变成这一表示形式,这称为浮点数的规格化表示。当浮点数的尾数为 0,不论其阶码为何值,或者当阶码的值遇到比它能表示的最小值还小时,不管其尾数为何值,计算机都把该浮点数看成零值,称为机器零。 

 这样float表示的最大数为:1.11111111111111111111111B×2^(0xFF-0x7F) 约为 3.4e+38,此外最小的正数为1B×2^(-0x7F)
约为5.88e-39。

 对于half类型,格式为阶符(S1),阶码(E5),尾数(M10),表示的数可记为(-1)^S * 2^(E-15) * (1 + M/2^10),最大的正数约为 1.99×2^16=65472,最小的正数为1/2^15 = 3.05e-5,可见虽然数的范围有限,但是表示几千位的还是绰绰有余。

 

下面希望在GPU计算中使用half代替float,因为存储的数据可以小一般,此外GPU有专门的硬件优化。

 

下面是网上摘抄的资料:

http://blog.vckbase.com/bruceteen/articles/240.html

标题:浮点类型深谈

1.编写本文目的
浮点运算已属常用,但仍有深究必要,以消除其中可能的错误使用。

2.预期读者

3.编者语
㈠ 在其他任何公共论坛上转载本文,请标明出处和作者,而无需授权和确认。

4.正文
㈠ float格式简谈
Inter 80386/80387 及以上型号CPU有三种浮点类型,即短实数、长实数和80位临时实数,分别占用4字节、8字节和10字节,对应着C/C++中的float、double和long double[注1],我以 Real4、Real8和Real0表示之。
每种浮点格式皆应符合IEEE标准,称为规格化数,不符合IEEE标准的浮点格式称为非格式化数(NAN),我以最简单的float格式举例。
Float格式数据长32 bits,最高位为符号位:0为正,1为负;紧接着的8位为阶码:为了便于比较大小,其固定偏移7FH长,即0实际表示-7FH,7FH实际表示0,0FFH实际表示80H;余下的低23位为尾数(有效数字),为了使有效数字达到最大精度,这23个有效数字隐含着固定位1[注2],比如尾数10000000000000000000001其实就是1.10000000000000000000001,1被省略,而小数点固定在首位。
根据以上规则可以知道float所能表示的绝对值大小范围是
0 000,0000,0 000,0000,0000,0000,0000,0000 B 至 
0 111,1111,1 111,1111,1111,1111,1111,1111 B
即±1.00000000000000000000000B×2(0x00-0x7F) 到±1.11111111111111111111111B×2(0xFF-0x7F)
然而事实上并不是这样,因为从这个范围可以看出它并不能表示0.0,而0.0为常用数字,所以特别规定±1.00000000000000000000000B×200为零,规定指数为0xFF的数字为非法数字,因此float实际的绝对值范围(除去0以外)是
0 000,0000,0 000,0000,0000,0000,0000,0001 B 至 
0 111,1111,0 111,1111,1111,1111,1111,1111 B
即 0 并上 ±1.00000000000000000000001B×2(0x00-0x7F) 到±1.11111111111111111111111B×2(0xFE-0x7F)
可能的格式状态:
+不支持
+非有效数
-不支持
-非有效数
+规格化
+∞
-规格化
-∞
+0
+空
-0
-空
+不能规格化
-不能规格化
可能的异常:
无效操作
上溢
下溢
除零
不可规格化操作数
精度不足
㈡ 注意事项
a. 可以看出0可以用+0表示,也可以用-0表示,为此,CPU在比较零值时作了特殊处理,结果是±0虽然在存储器上格式不同,但比较值相同,然而如果是用字节来比较float类型大小时却需要注意这一点。
b. 运算上溢的值不是实际值,而是特值 0 111,1111,0 000,0000,0000,0000,0000,0000 B,例如 1.0×2127 + 1.5×2127 不等于 1.5×2128,虽然它有能力表示1.5×2128。
c. 
㈢ 在C++中的部分解决方案及遗留问题

5.参考资料
《Inter 80X86/80387 汇编指南》

6.附录
[注1]:M$认为double精度已足够,故在MVC++5.0及以后取消80位了临时实数,令long double等同于double,但在本文中的long double还是指80位临时实数。
[注2]:各种浮点类型格式类似,double指数偏移基数3FFH,long double指数偏移基数3FFFH,但long double特殊在无有效数字隐含位。
real04:符号位1,阶码08(固定偏移  7F),尾数23,固定隐含位有;
real08:符号位1,阶码11(固定偏移 3FF),尾数52,固定隐含位有;
real10:符号位1,阶码15(固定偏移3FFF),尾数64,固定隐含位无;

http://songofsilence.bokee.com/view.b?diaryId=10285893
评论次数(0)  |  浏览次数(1857)  |  类型(基础) |  收藏此文  | 
 
 请输入验证码  (提示:点击验证码输入框,以获取验证码