浮點數運算和整數運算相比,只能進行加減乘除這些數值運算,不能做位運算和移位運算。
在計算機中,浮點數雖然表示的范圍很大,但是浮點數有個非常重要的特點,就是浮點數常常無法精確表示
舉例
浮點數0.1
在計算機中就無法精確表示,因為十進制的0.1
換算成二進制是一個無限循環小數,很顯然,無論使用float
還是double
,都只能存儲一個0.1
的近似值。但是,0.5
這個浮點數又可以精確地表示。因為浮點數常常無法精確表示,因此,浮點數運算會產生誤差:
public class Main { public static void main(String[] args) { double x=1.0 / 10; double y=1-9.0 / 10; System.out.println(x); System.out.println(y); } }
運行結果
0.1 0.09999999999999998
由於浮點數存在運算誤差,所以比較兩個浮點數是否相等常常會出現錯誤的結果。正確的比較方法是判斷兩個浮點數之差的絕對值是否小於一個很小的數:
public class Main { public static void main(String[] args) { double x=1.0 / 10; double y=1-9.0 / 10; System.out.println(x); System.out.println(y); double r=Math.abs(x-y); if(r<0.00001) { System.out.println("true"); } else { System.out.println("false"); } } }
浮點數在內存的表示方法和整數比更加復雜。Java的浮點數完全遵循IEEE-754標准,這也是絕大多數計算機平台都支持的浮點數標准表示方法。
類型提升
如果參與計算的兩個數其中一個是整型,那么整型可以自動提升到浮點型
public class Main { public static void main(String[] args) { int n=5; double d=1.2+24.0/n; System.out.println(d); //6.0 } }
需要特別注意,在一個復雜的四則運算中,兩個整數的運算不會出現自動提升的情況。例如:
double d = 1.2 + 24 / 5; // 5.2
計算結果為4.2,原因是編譯器計算24/5這個子表達式時,按兩個整數進行運算,結果為4,而不是按浮點運算4.8
溢出
整數運算在除數為0
時會報錯,而浮點數運算在除數為0
時,不會報錯,但會返回幾個特殊值:
NaN
表示Not a NumberInfinity
表示無窮大-Infinity
表示負無窮大
例如
double d1 = 0.0 / 0; // NaN double d2 = 1.0 / 0; // Infinity double d3 = -1.0 / 0; // -Infinity
這三種特殊值使用較少
強制轉型
可以將浮點數強制轉型為整數,在轉型時,浮點數的小數部分會被丟棄。如果轉型后超過了整型能表示的最大范圍,將返回整型最大值
public class Main { public static void main(String[] args) { int n1=(int) 12.3; //12 System.out.println(n1); int n2=(int) 12.7; //12 System.out.println(n2); int n3=(int) -12.7; //-12 System.out.println(n3); int n4=(int) 9999999991.11; //2147483647 System.out.println(n4); } }
小結
浮點數無法精確表示,並且浮點數的運算結果可能有誤差。
比較兩個浮點數通常比較他們的絕對值之差是否小於一個特定值。
整型和浮點型運算時,整型會自動提升為浮點型。
可以將浮點型強制轉換為整型,但超出范圍后將始終返回整型的最大值。