在 Java 中將雙精度數截斷為小數點後兩位
1. 概述
在本教程中,我們將了解 Java 中用於將double
數截斷至小數點後兩位的一系列選項。我們將看到留下String
方法以及返回Numbers
的選項。
2.使用Math.floor()
和Math.ceil()
舍入
我們要檢查的第一個方法是使用Math
類別刪除多餘的小數位。要將正數截斷到小數點後兩位,我們先將double
度乘以 100,將所有要保留在小數點前面的數字移動。接下來,我們使用Math.floor()
進行向下捨入,刪除小數點後的所有內容。最後,我們除以 100 來撤銷先前的乘法:
@Test
void givenADouble_whenUsingMath_truncateToTwoDecimalPlaces(){
double positive = 1.55555555;
double truncated = Math.floor(positive * 100) / 100;
assertEquals("1.55", String.valueOf(truncated));
double negative = -1.55555555;
double negativeTruncated = Math.ceil(negative * 100) / 100;
assertEquals("-1.55", String.valueOf(negativeTruncated));
}
對於負數,過程幾乎相同,但我們不使用Math.floor(),
而是使用Math.ceil()
進行向上舍入。我們可以添加額外的程式碼來檢測double
數是負數還是正數,並根據需要自動使用正確的方法。
為了刪除更多或更少的小數位,我們會在乘除的數字中添加或刪除零。例如,要保留三位小數,我們需要乘以和除以 1000。如果我們需要將double
保留為double
而不最終將其轉換為String.
3.使用String.format()
讓我們繼續討論為顯示目的而不是計算目的而設計的選項。我們將從這些方法中傳回一個String
,但如果需要,總是可以將結果轉換回double
。 String.format()
方法有兩個參數。首先,我們要套用的格式,其次,格式所引用的參數。要截斷到兩位小數,我們將使用格式String
“%.2f”:
@Test
void givenADouble_whenUsingStringFormat_truncateToTwoDecimalPlaces() {
double positive = 1.55555555;
String truncated = String.format("%.2f", positive);
assertEquals("1.56", truncated);
double negative = -1.55555555;
String negativeTruncated = String.format("%.2f", negative);
assertEquals("-1.56", negativeTruncated);
}
格式String
末尾的「f」指示格式化程式產生小數格式,「.2」表示我們需要小數點後兩位數字。我們可以調整它以截斷到所需的小數位數。我們可以在測試中看到結果實際上是四捨五入而不是截斷,因此根據我們的要求,這可能不合適。
4. 使用NumberFormat
建立String
NumberFormat
是一個抽象類,旨在讓我們格式化任何數字。因為它是一個抽象類,所以我們需要先使用getNumberInstance()
來接收我們可以使用的物件。請注意,除非我們指示它否則,否則這將使用我們的預設區域設定。我們可以透過使用setMaximumFractionDigits()
來表示我們想要多少位小數。最後,因為我們想要截斷而不是捨入,所以我們使用參數RoundingMode.DOWN
呼叫setRoundingMode()
:
@Test
public void givenADouble_whenUsingNumberFormat_truncateToTwoDecimalPlaces(){
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setRoundingMode(RoundingMode.DOWN);
double value = 1.55555555;
String truncated = nf.format(value);
assertEquals("1.55", truncated);
double negativeValue = -1.55555555;
String negativeTruncated = nf.format(negativeValue);
assertEquals("-1.55", negativeTruncated);
}
透過我們的 NumberFormat 設置,就像使用double
呼叫format()
一樣簡單。在上面的測試中,我們可以看到它對於正數和負數的表現同樣好。
5. 使用DecimalFormat
建立String
DecimalFormat
是NumberFormat
的子類,專為小數設計。它是一個具體的類,因此我們可以直接創建它的實例,並將所需的模式傳遞給建構函數。我們將傳入「#.##」。這裡,小數點後的雜湊數表示要保留的數量:
@Test
public void givenADouble_whenUsingDecimalFormat_truncateToTwoDecimalPlaces(){
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.DOWN);
double value = 1.55555555;
String truncated = df.format(value);
assertEquals("1.55", truncated);
double negativeValue = -1.55555555;
String negativeTruncated = df.format(negativeValue);
assertEquals("-1.55", negativeTruncated);
}
與之前的NumberFormat
一樣,我們指定了RoundingMode.DOWN
的使用。我們再次看到該解決方案可以很好地處理正數和負數,因此非常有用。
6. BigDecimal
的最佳精度
Java 的BigDecimal
類別最適合直接處理截斷小數位,同時將結果保留為我們可以使用的數字。如果可以使用它而不是double,
它可能是最好的選擇。我們可以透過將double
值傳遞給建構函式並直接告訴它透過同時向下捨去保留兩位小數來建立BigInteger
:
@Test
void givenADouble_whenUsingBigDecimal_truncateToTwoDecimalPlaces(){
BigDecimal positive = new BigDecimal(2.555555).setScale(2, RoundingMode.DOWN);
BigDecimal negative = new BigDecimal(-2.555555).setScale(2, RoundingMode.DOWN);
assertEquals("2.55", positive.toString());
assertEquals("-2.55", negative.toString());
}
出於此測試的目的,我們已將結果轉換為String
,以便在視覺上清楚地了解結果是什麼。然而,如果我們願意的話,我們可以使用截斷的輸出繼續執行進一步的計算。
七、結論
我們已經研究了在 Java 中截斷double
的五種不同方法。我們已經看到,如果我們在輸出String
時建立用於顯示目的的內容,則String.format()
、 NumberFormat,
和DecimalFormat
是可用的。當然,我們總是可以使用Double.parseDouble()
將String
轉換回doubles
。或者,我們可以使用Math
類或BigDecimal
將截斷值保留為數字以進行進一步計算。
與往常一樣,範例的完整程式碼可在 GitHub 上取得。