首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java float double为啥精度会丢失

2012-12-26 
java float double为什么精度会丢失由于对float或double?的使用不当,可能会出现精度丢失的问题。问题大概情

java float double为什么精度会丢失

由于对float或double?的使用不当,可能会出现精度丢失的问题。问题大概情况可以通过如下代码理解:

?

public class FloatDouble{public static void main(String[] args){double d = 8;long l = Double.doubleToLongBits(d);System.out.println(Long.toBinaryString(l));float f = 8;int i = Float.floatToIntBits(f);System.out.println(Integer.toBinaryString(i));}}
?

?

输出结果如下:

?

Double:100000000100000000000000000000000000000000000000000000000000000

Float:1000001000000000000000000000000

对于输出结果分析如下。对于都不?double?的二进制左边补上符号位?0?刚好可以得到?64?位的二进制数。根据double的表 示法,分为符号数、幂指数和尾数三个部分如下:

0?10000010111?0011000101100111100101110000000000000000000000000000

对于?float?左边补上符 号位?0?刚好可以得到?32?位的二进制数。?根据float的表示法,?也分为?符号数、幂指数和尾数三个部分如下?:

0?10010111?00110001011001111001100

绿色部分是符号位,红色部分是幂指数,蓝色部分是尾数。

对比可以得出:符号位都是?0?,幂指数为移码表示,两者刚好也相等。唯一不同的是尾数。

在?double?的尾数 为:?001100010110011110010111?0000000000000000000000000000?,省略后面的零,至少需要24位才能正确表示?。

而在?float?下面尾数 为:?00110001011001111001100?,共?23?位。

为什么会这样?原因很明显,因为?float尾数?最多只能表示?23?位,所以?24?位的?001100010110011110010111?在?float?下面经过四舍五入变成了?23?位的?00110001011001111001100?。所以?20014999?在?float?下面变成了?20015000?。
也就是说?20014999?虽然是在float的表示范围之内,但?在?IEEE 754?的?float?表示法精度长度没有办法表示出?20014999?,而只能通过四舍五入得到一个近似值。

总结:

浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是 因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用?float?和?double?作精确运 算的时候要特别小心。
可以考虑采用一些替代方案来实现。如通过?String?结合?BigDecimal?或 者通过使用?long?类型来转换。

?

?

?

?

?

热点排行