java学习日记05——java中的浮点数剖析

来源:互联网 发布:mysql select 锁表 编辑:程序博客网 时间:2024/06/06 16:33

这几天一直看《java的浮点数剖析》这篇文章(http://jiangzhengjun.iteye.com/blog/636761)。

1:所谓浮点数是相对于定点数而言的。定点数的缺点是:固定的小数点位置决定了固定位数的整数和小数部分,不利于同时表达特别大和特别小的数。而浮点数利用科学计数法表示实例,分为尾数、基数、指数、表正负的符号四部分。

2:java平台上的float、double采纳IEEE 754中所定义的32位、64位浮点数的格式,将特定长度的连续字节的所有二进制位分割为特定宽度的符号域、指数域、尾数域三个域,分别表示符号、指数、尾数

3:在指数位上,为了表示负数,通常有一个偏差(bias),在单精度中是127,双精度中是1023,即指数位-127=实际的指数位,指数位的表示范围是-127(全0)~128(全1)

 

4:在尾数域上,单精度数为 23 位长,双精度数为 52 位长。除了某些特殊值外,IEEE 标准要求浮点数必须是规范的。这意味着尾数的小数点左侧必须为 1,因此我们在保存尾数的时候,可以省略小数点前面这个 1,从而腾出一个二进制位来保存更多的尾数。这样我们实际上用 23 位长的尾数域表达了 24 位的尾数。比如对于单精度数而言,二进制的 1001.101(对应于十进制的 9.625)可以表达为 1.001101 × 2^3,所以实际保存在尾数域中的值为 00110100000000000000000,即去掉小数点左侧的 1,并用 0 在右侧补齐。
      值得注意的是,对于单精度数,由于我们只有 24 位的尾数(其中一位隐藏),所以可以表达的最大尾数为 2^24- 1 = 16,777,215。特别的,16,777,216 是偶数,所以我们可以
通过将它除以 2 并相应地调整指数来保存这个数,这样 16,777,216 同样可以被精确的保存。相反,数值 16,777,217 则无法被精确的保存。由此,我们可以看到单精度的浮点数可以表达的十进制数值中,真正有效的数字不高于 8 位。事实上,对相对误差的数值分析结果显示有效的精度大约为 7.22 位(由于位数不可取小数,所以单精度的精度为7,即可精确到小数点后7位)。

 

 

0 0