解決double的值相加的問題
阿新 • • 發佈:2018-07-20
eval writing plain assume ply creates att pear 值轉換
針對double類型的計算的問題之一:
public class DoubleCaculator { double price = 0.38; int count = 3; @Test public void demo1() { //結果:1.1400000000000001 System.out.println(price * count); } }
@Test public void demo2() { //bigDecimal的字符串的構造完美解決了double計算的問題 BigDecimal bdP = newBigDecimal(price); BigDecimal bdc = new BigDecimal(count); BigDecimal add = bdP.multiply(bdc); System.out.println(add.doubleValue()); }
此結果是:2.2800000000000002
從上面兩個的結果,顯然與我們想要的結果有點不一樣,如果是針對金融方面的話,那麽一個小數點的問題就會影響很大,那麽對於這樣的問題,我們要如何的解決哪?
答:BigDecimal這個類。
那為啥上面使用了這個BigDecimal為啥還會出現這個問題?
答:傳入的參數有問題。
源碼的註釋說明:如果B中傳入的為double類型的值時的解釋
The results of this constructor can be somewhat unpredictable. * One might assume that writing {@code new BigDecimal(0.1)} in * Java creates a {@code BigDecimal} which is exactly equal to * 0.1 (an unscaled value of 1, with a scale of 1), but it is* actually equal to * 0.1000000000000000055511151231257827021181583404541015625. * This is because 0.1 cannot be represented exactly as a * {@code double} (or, for that matter, as a binary fraction of * any finite length). Thus, the value that is being passed * <i>in</i> to the constructor is not exactly equal to 0.1, * appearances notwithstanding. *
以及給出的最佳的解決方法:
The {@code String} constructor, on the other hand, is * perfectly predictable: writing {@code new BigDecimal("0.1")} * creates a {@code BigDecimal} which is <i>exactly</i> equal to * 0.1, as one would expect. Therefore, it is generally * recommended that the {@linkplain #BigDecimal(String) * <tt>String</tt> constructor} be used in preference to this one. *
所以上面的代碼如果將傳入的double類型的值轉換成字符串的話,那麽問題就解決了:
@Test public void demo2() { //bigDecimal的字符串的構造完美解決了double計算的問題 BigDecimal bdP = new BigDecimal(price + ""); BigDecimal bdc = new BigDecimal(count + ""); BigDecimal add = bdP.multiply(bdc); System.out.println(add.doubleValue()); }
解決double的值相加的問題