浮點型變數/常量
帶小數的資料在Java中稱為浮點型。浮點型可分為float型別和double型別。
表2-5 浮點型資料型別 |
||
型別 |
佔用儲存空間 |
表數範圍 |
float |
4位元組 |
-3.403E38~3.403E38 |
double |
8位元組 |
-1.798E308~1.798E308 |
float型別又被稱作單精度型別,尾數可以精確到7位有效數字,在很多情況下,float型別的精度很難滿足需求。而double表示這種型別的數值精度約是float型別的兩倍,又被稱作雙精度型別,絕大部分應用程式都採用double型別。浮點型常量預設型別也是double。
Java浮點型別常量有兩種表示形式
-
十進位制數形式,例如:3.14 314.0 0.314
-
科學記數法形式,如314e2 314E2 314E-2
【示例2-11】使用科學記數法給浮點型變數賦值
double f = 314e2; //314*10^2-->31400.0 double f2 = 314e-2; //314*10^(-2)-->3.14
|
float型別的數值有一個字尾F或者f ,沒有後綴F/f的浮點數值預設為double型別。也可以在浮點數值後新增字尾D或者d, 以明確其為double型別。
【示例2-12】float型別賦值時需要新增字尾F/f
float f = 3.14F; double d1 = 3.14;
double d2 = 3.14D;
|
老鳥建議
-
浮點型別float,double的資料不適合在不容許舍入誤差的金融計算領域。如果需要進行不產生舍入誤差的精確數字計算,需要使用BigDecimal類。
【示例2-13】浮點數的比較一
float f = 0.1f;
double d = 1.0/10;
System.out.println(f==d);//結果為false
|
【示例2-14】浮點數的比較二
float d1 = 423432423f;
float d2 = d1+1;
if(d1==d2){
System.out.println("d1==d2");//輸出結果為d1==d2
}else{
System.out.println("d1!=d2");
}
|
執行以上兩個示例,發現示例2-13的結果是“false”,而示例2-14的輸出結果是“d1==d2”。這是因為由於字長有限,浮點數能夠精確表示的數是有限的,因而也是離散的。 浮點數一般都存在舍入誤差,很多數字無法精確表示(例如0.1),其結果只能是接近, 但不等於。二進位制浮點數不能精確的表示0.1、0.01、0.001這樣10的負次冪。並不是所有的小數都能可以精確的用二進位制浮點數表示。
java.math包下面的兩個有用的類:BigInteger和BigDecimal,這兩個類可以處理任意長度的數值。BigInteger實現了任意精度的整數運算。BigDecimal實現了任意精度的浮點運算。
菜鳥雷區
1.不要使用浮點數進行比較!很多新人甚至很多理論不紮實的有工作經驗的程式設計師也會犯這個錯誤!需要比較請使用BigDecimal類
【示例2-15】使用BigDecimal進行浮點數的比較
import java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
BigDecimal bd = BigDecimal.valueOf(1.0);
bd = bd.subtract(BigDecimal.valueOf(0.1));
bd = bd.subtract(BigDecimal.valueOf(0.1));
bd = bd.subtract(BigDecimal.valueOf(0.1));
bd = bd.subtract(BigDecimal.valueOf(0.1));
bd = bd.subtract(BigDecimal.valueOf(0.1));
System.out.println(bd);//0.5
System.out.println(1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1);//0.5000000000000001
}
}
|
浮點數使用總結
-
預設是double型別
-
浮點數存在舍入誤差,數字不能精確表示。如果需要進行不產生舍入誤差的精確數字計算,需要使用BigDecimal類。
-
避免比較中使用浮點數,需要比較請使用BigDecimal類
import java.math.*; /** * 測試浮點型別 * @author Administrator * */ public class TestPrimitiveDataType2 { public static void main(String[]args) { float a=3.14F;//浮點型常量預設是double型別 double b=6.28; double c=628E-2;//628除以100 System.out.println(c); //浮點數是不精確的,一定不要用於比較 float f=0.1F; double d=1.0/10;//等於0.1 System.out.println(f==d);//結果是false float d1=423432423f; float d2=d1+1; if(d1==d2) { System.out.println("d1==d2");//結果竟然是d1==d2 }else { System.out.println("d1!=d2"); } System.out.println("##############"); //使用精確浮點執行,推薦 BigDecimal BigDecimal bd = BigDecimal.valueOf(1.0); bd = bd.subtract(BigDecimal.valueOf(0.1));//subtract是減法 bd = bd.subtract(BigDecimal.valueOf(0.1)); bd = bd.subtract(BigDecimal.valueOf(0.1)); bd = bd.subtract(BigDecimal.valueOf(0.1)); bd = bd.subtract(BigDecimal.valueOf(0.1)); System.out.println(bd);//0.5 System.out.println(1.0 - 0.1 - 0.1 - 0.1 - 0.1 - 0.1);//0.5000000000000001 BigDecimal bd2=BigDecimal.valueOf(0.1); BigDecimal bd3=BigDecimal.valueOf(1.0/10); System.out.println(bd2.equals(bd3));//db2==bd3 } }