日期:2014-05-20  浏览次数:20860 次

一个float的怪问题

public   class   Test   {

 
public   static   void   main(String[]   args)   {
//   TODO   自动生成方法存根
float   f=1.111111111111f;
float   g=1.222222222222f;
 
System.out.println(f);
System.out.println(g);
}
}

结果:
1.1111112
1.2222222

为什么第一个是有个 "2 "的?


------解决方案--------------------
涉及机器码存储的问题,三言两语怎么说的清楚!
简单来说,一般浮点数存储大多采用的IEEE754浮点数格式:4字节数它使用7位做阶码,一位符号位,23位尾数。存储办法是把数字转成二进制表示后,通过移动N(这个就是阶码,小数点左移为正,右移为负)位使之变成1.*******这样的格式。然后,把尾数[*******]存储在尾数里边(因为都是1.多,所以可以省略的) 如果[*******]位数超过23位,只取前23位并对第24位进行取舍(取1舍0)。 更详细的自己找书看吧

从下例可以看到:取舍之后,1.111111=1.1111111 1.1111112=1.11111111
(用再长的1也影响不到进位了,所以......)

public class Temp {
public static void main(String[] agras) {
BigDecimal bd = new BigDecimal( "0.111111 ");
bd = bd.multiply(new BigDecimal(2).pow(23));
System.out.println(bd);
bd = new BigDecimal( "0.1111111 ");
bd = bd.multiply(new BigDecimal(2).pow(23));
System.out.println(bd);
bd = new BigDecimal( "0.11111111 ");
bd = bd.multiply(new BigDecimal(2).pow(23));
System.out.println(bd);
bd = new BigDecimal( "0.1111112 ");
bd = bd.multiply(new BigDecimal(2).pow(23));
System.out.println(bd);
}
}
output:
932066.623488
932067.4623488
932067.54623488
932068.3012096