由於電腦在計算過程中的舍入關係,普通的計算和工程計算可能會出現計算不足夠精確的情況,這種情況在這兩種計算中也許是可以忍受的,但是在商務運算中就不可接受了,財務計算。
//import org.zym.arithutil.Arith; </p><p>public class FloatCalculation { </p><p> /**<br /> * @param args<br /> */<br /> public static void main(String[] args) {<br /> System.out.println(0.05 + 0.01);<br />// System.out.println(Arith.add(0.05,0.01)); </p><p> System.out.println(4.015 * 100);<br />// System.out.println(Arith.mul(4.015,100));<br /> } </p><p>}<br />
其計算結果:
0.060000000000000005
401.49999999999994
這顯然是不能接受的。
下面給出一個算術類工具來解決這個問題,基本原則是使用java.math.BigDecimal類來進行加減乘除的運算封裝。
package org.zym.arithutil;<br />import java.math.BigDecimal; </p><p>public class Arith{<br /> //預設除法運算精度<br /> private static final int DEF_DIV_SCALE = 10;<br /> //這個類不能執行個體化<br /> private Arith(){<br /> } </p><p> /**<br /> * 提供精確的加法運算。<br /> * @param v1 被加數<br /> * @param v2 加數<br /> * @return 兩個參數的和<br /> */<br /> public static double add(double v1,double v2){<br /> BigDecimal b1 = new BigDecimal(Double.toString(v1));<br /> BigDecimal b2 = new BigDecimal(Double.toString(v2));<br /> return b1.add(b2).doubleValue();<br /> }<br /> /**<br /> * 提供精確的減法運算。<br /> * @param v1 被減數<br /> * @param v2 減數<br /> * @return 兩個參數的差<br /> */<br /> public static double sub(double v1,double v2){<br /> BigDecimal b1 = new BigDecimal(Double.toString(v1));<br /> BigDecimal b2 = new BigDecimal(Double.toString(v2));<br /> return b1.subtract(b2).doubleValue();<br /> }<br /> /**<br /> * 提供精確的乘法運算。<br /> * @param v1 被乘數<br /> * @param v2 乘數<br /> * @return 兩個參數的積<br /> */<br /> public static double mul(double v1,double v2){<br /> BigDecimal b1 = new BigDecimal(Double.toString(v1));<br /> BigDecimal b2 = new BigDecimal(Double.toString(v2));<br /> return b1.multiply(b2).doubleValue();<br /> } </p><p> /**<br /> * 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到<br /> * 小數點以後10位,以後的數字四捨五入。<br /> * @param v1 被除數<br /> * @param v2 除數<br /> * @return 兩個參數的商<br /> */<br /> public static double div(double v1,double v2){<br /> return div(v1,v2,DEF_DIV_SCALE);<br /> } </p><p> /**<br /> * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指<br /> * 定精度,以後的數字四捨五入。<br /> * @param v1 被除數<br /> * @param v2 除數<br /> * @param scale 表示表示需要精確到小數點以後幾位。<br /> * @return 兩個參數的商<br /> */<br /> public static double div(double v1,double v2,int scale){<br /> if(scale<0){<br /> throw new IllegalArgumentException(<br /> "The scale must be a positive integer or zero");<br /> }<br /> BigDecimal b1 = new BigDecimal(Double.toString(v1));<br /> BigDecimal b2 = new BigDecimal(Double.toString(v2));<br /> return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();<br /> } </p><p> /**<br /> * 提供精確的小數位四捨五入處理。<br /> * @param v 需要四捨五入的數字<br /> * @param scale 小數點後保留幾位<br /> * @return 四捨五入後的結果<br /> */<br /> public static double round(double v,int scale){<br /> if(scale<0){<br /> throw new IllegalArgumentException(<br /> "The scale must be a positive integer or zero");<br /> }<br /> BigDecimal b = new BigDecimal(Double.toString(v));<br /> BigDecimal one = new BigDecimal("1");<br /> return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();<br /> }<br />}<br />
看下面的代碼:
import org.zym.arithutil.Arith; </p><p>public class FloatCalculation { </p><p> /**<br /> * @param args<br /> */<br /> public static void main(String[] args) {<br /> System.out.println(0.05 + 0.01);<br /> System.out.println(Arith.add(0.05,0.01)); </p><p> System.out.println(4.015 * 100);<br /> System.out.println(Arith.mul(4.015,100)); </p><p> } </p><p>}<br />
對比計算結果如下: 寫道0.060000000000000005
0.06
401.49999999999994
401.5
得到了令人滿意的效果,其他兩種計算大家可以自己測試,這樣就解決了一些要求精確的商務誰計算的問題,整理下,以方便大家和自己使用。