float與double在java中很多人都知道有精度問題缕探,對于浮點數(shù)不能直接進(jìn)行比較缅疟,下面幾個高頻的關(guān)于浮點數(shù)的面試題,你會不會呢淮菠?
float a1 = 0.1f;
double a2 = 0.1;
System.out.println((a1 - a2) == 0.0);
float b1 = 0.125f;
double b2 = 0.125;
System.out.println((b1 - b2) == 0.0);
double c1 = 0.625;
double c2 = 0.5;
double c3 = 0.375;
System.out.println((c1 - c2) == (c2 - c3));
double d1 = 0.8;
double d2 = 0.6;
double d3 = 0.4;
System.out.println((d1 - d2) == (d2 - d3));
答案為:
false
true
true
false
我們知道計算機(jī)表示數(shù)字使用的是二進(jìn)制捌臊。對于整數(shù),轉(zhuǎn)換成二進(jìn)制比較簡單兜材,比如5=101;對于小數(shù)逞力,需要對小數(shù)的前后部分分開計算曙寡,比如5.5=101.1蝠嘉。
詳細(xì)的講解參考網(wǎng)上其他內(nèi)容吞琐,例如:http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html等
對于整數(shù)部分計算成二進(jìn)制比較簡單痊银,對于小數(shù)后計算二級制一般采用 乘2取整法
例如:0.3
0.3x2=0.6忿等,取小數(shù)后第一位為0设易,當(dāng)前為0.0
0.6x2=1.2般堆,取小數(shù)后第二位為1剔猿,當(dāng)前為0.01
0.2x2=0.4硕糊,取小數(shù)后第三位為0峦嗤,當(dāng)前為0.010
0.4x2=0.8蕊唐,取小數(shù)后第四位為0,當(dāng)前為0.0100
0.8x2=1.6烁设,取小數(shù)后第五位為1替梨,當(dāng)前為0.01001
......
我們發(fā)現(xiàn)對于小數(shù)后計算出來的二進(jìn)制會出現(xiàn)精度問題,這個時候你已經(jīng)明白了為什么0.1比較為false,0.125比較為true的原因了
繼續(xù)深入
System.out.println(1.0 / 0);
System.out.println(0.0 / 0);
System.out.println(1 / 0);
輸出:
Infinity
NaN
java.lang.ArithmeticException: / by zero
這個是因為浮點數(shù)在二進(jìn)制中只能表示為大概值弓熏,所以在Java中浮點數(shù)有無限值和無意義非數(shù)字的概念,即Infinity與NaN
但是對于整數(shù)信认,0是不能當(dāng)作除數(shù)的