CodeGym /課程 /JAVA 25 SELF /浮點數與型別 double 入門

浮點數與型別 double 入門

JAVA 25 SELF
等級 6 , 課堂 2
開放

1. 小數

假設你打算寫一個最簡單的計算機,或任何需要計算的程式(從計算金錢到複雜的物理)。現實世界中很多東西都不是整數,這是改不了的事實!

那就讓我們武裝一個新的資料型別吧!

在程式設計中,小數也稱為實數,或浮點數floating-point)。在 Java(以及多數語言)中,它們用來儲存不僅是整數,還有「小數」的數值:像是 3.14-28.572.718281828 等等。

實數主要有兩種型別:

型別 內容 值域(約) 精確度 典型大小
float
數值 ±1.5 × 10-45 ... ±3.4 × 1038 約 7 位有效數字 4 位元組
double
數值 ±5.0 × 10-324 ... ±1.7 × 10308 約 15–16 位有效數字 8 位元組

型別 float

float 的名稱來自 floating-point number——浮點數。數學中的實數有其確定的性質,而電腦有許多限制。因此在 Java 中把小數稱為「實數」並不嚴謹,通常稱為「浮點數」更為恰當。

float 通常可儲存 7 位有效數字(例如 0.1234567)、十的冪次,並在記憶體中占用 4 位元組。對精確計算而言這很有限,因此大家很快就改用雙精度的數值。

型別 double

double 的名稱來自 雙精度(double precision)。它在記憶體中占用 8 位元組(是 float 的兩倍),可儲存最多約 15 位有效數字:0.123456789012345。這對大多數含小數的計算已相當足夠,因此在 Java 中,double 是儲存小數的主要型別。

本講的重點將放在 double:預設情況下,它被建議用於所有「一般」的小數。不過接下來我們也會看看 float 型別。

2. 宣告與初始化 double 型別的變數

int 一樣——只是現在改用 double

// 宣告變數並指定圓周率的值
double pi = 3.1415926;

// 也可以先宣告不初始化
double averageSalary;
averageSalary = 91234.56;

// 可以做運算!
double pizzaPieces = 8;
double friends = 3;
double piecesPerFriend = pizzaPieces / friends; // 2.666...(不是 2)

語法要點:

  • 十進位的小數點使用 句點3.14)。如果使用逗號——會得到編譯錯誤!
  • 嚴格來說,寫成 double d = 3; 也不會報錯——型別會自動轉換(整數會無損地轉成「浮點數」)。

3. 使用 Scanner 輸入與輸出小數

先試著輸出一個小數:

double amount = 42.75;
System.out.println(amount); // 會輸出:42.75

很順利!如果加上文字:

System.out.println("您的帳戶餘額:" + amount + " 歐元。"); // 輸出:您的帳戶餘額:42.75 歐元。

鍵盤輸入

要讀取 double,需要使用 Scanner 類別的專用方法:console.nextDouble()

Scanner console = new Scanner(System.in);

System.out.println("請輸入室外溫度:");
double temperature = console.nextDouble(); // 直接讀入 double

System.out.println("現在室外:" + temperature + " 度。");

4. 型別 double 實戰:算術運算

所有常見的運算(+-*/)都和 int 一樣可用:

double distance = 100.5;
double time = 2.0;
double speed = distance / time; // 50.25

System.out.println("平均速度:" + speed); // 平均速度:50.25

這就是全部的算術差異。唯一的不同:如果至少有一個運算元是 double,除法的結果一定是小數。

int 比較

int a = 5, b = 2;
System.out.println(a / b); // 2(餘數被捨去)

double aa = 5, bb = 2;
System.out.println(aa / bb); // 2.5

5. 使用 double 的常見錯誤與奇妙現象

輸入轉換錯誤

經典情境:使用者輸入 3,14,但程式預期 3.14。在 Java 中,Scanner.nextDouble() 依賴目前的地區設定(Locale):在俄/德等地區設定中逗號可用,在英語地區設定中需要句點。如有需要,請為 Scanner 設定 Locale,或先讀字串再自行解析。

// 在 Locale.US 下,如果輸入「3,14」會出問題
double value = console.nextDouble();

電腦中數值「不精確」的問題

這裡常讓新手有點困惑:

double x = 0.1 + 0.2;
System.out.println(x); // 嗯……0.30000000000000004

恭喜,你遇到了電腦內部表示小數的「魔法」。事實上,許多數值在二進位制中無法被精確表示。對多數應用來說這通常不成問題,但在金融與精密科學中就有一些需要注意的細節。

6. 重要:doubleint——自動與顯式轉換

有時你把整數和小數相加,或把 int 指派給 double 變數——都不會出錯:

int i = 2;
double d = i; // 一切正常!
System.out.println(d); // 2

double dd = 3.7;
int ii = (int) dd; // 需要顯式把 double 轉成 int!
System.out.println(ii); // 3,小數部分被捨去

這常讓人意外——為什麼轉型後小數部分不見了?因為 int 不能儲存小數(小數點後的部分會永久消失)。

更多關於從 doubleint 的轉換,以及運算子 (int) 的內容,將在下一堂課討論。

7. 格式化輸出:把 double 漂亮地印出

預設印出 double 時常會帶一堆多餘的位數。可以格式化輸出:

double temp = 23.56789;
System.out.println(temp); // 23.56789

// 小數點後 2 位
System.out.println(String.format("%.2f", temp)); // 23.57

// 小數點後 1 位
System.out.println(String.format("%.1f%n", temp)); // 23.6
格式 結果 說明
"%.2f"
23.57 小數點後 2 位
"%.1f"
23.6 小數點後 1 位

8. 使用 floatdouble 的常見錯誤

錯誤 №1:將 double 隱式轉換為 float

float f = 1.23; // 錯誤!

編譯器會不高興:「你正試圖把 double 放進 float——這可能導致精度損失!」請務必加上後綴 f

錯誤 №2:忘了兩個 int 相除會得到 int 結果

int a = 7, b = 2;
double result = a / b; // 3.0,而不是 3.5

要得到小數,請顯式轉型至少一個運算元:

double result = (double) a / b; // 3.5

錯誤 №3:比較小數

不要用 == 來比較小數是否相等。請使用帶有小容差(epsilon)的比較。

錯誤 №4:float 的精度損失

不要把很大的數或需要非常精確的值存進 float——它們可能「壞掉」或丟失重要位數。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION