先看demo:
public class L26 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // double a= 300000; double x= 300000.00000000003;//double比較,小數點后有效位 double y= 300000.000000000003;//主要注意的是double類型直接==/>=/<=的比較,涉及到有效位 System.out.println(x<=300000); System.out.println(y<=300000); } } /* *output: *false true * */
總結:double是雙精度基本數據類型,double與double之間,涉及==(包括>=,<=)的比較,就得考慮double的精度問題。
如上面的例子,
當x=300000.00000000003,與
300000比較,得到的是false,說明300000.00000000003>300000;
當y=300000.000000000003,與
300000比較,得到的是true,說明300000.00000000003<=300000;(jvm實際判定的是300000.000000000003==300000)猛然看上去,感覺不對啊,應該是大於啊。這就是double的精度問題。當小數點后位數 大於(17-6)11位時,jvm就會忽略這個精度,這時的y=300000.00000000000。所以jvm就會判定y==300000.
這種情況,我們在開發時如果需要更精確的比較double類型,就要用到 BigDecimal 這個類了。
上面我為什么用17-6呢?看下這個例子:
public static void main(String[] args) { double x= 3.0000000000000003;//double比較,小數點后有效位:17-(整數位)。總有效位為17位 double y= 30.000000000000003;//17位數字 double z= 300.00000000000003; double w= 3000.0000000000003; System.out.println(x==3); System.out.println(y==30); System.out.println(z==300); System.out.println(w==3000); System.out.println("--------------------分界線-------------------"); //小數后都加一個0 double x1= 3.00000000000000003;//18位數字 double y1= 30.0000000000000003; double z1= 300.000000000000003; double w1= 3000.00000000000003; System.out.println(x1==3); System.out.println(y1==30); System.out.println(z1==300); System.out.println(w1==3000); } } /* output: false false false false --------------------分界線------------------- true true true true */