1. 程式人生 > 實用技巧 >util之精度計算工具類

util之精度計算工具類

package com.xxx.tools;

import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @ClassName: DoubleTool
 * @Description: java類精確計算小數
 * double的計算不精確,會有類似0.0000000000000002的誤差,正確的方法是使用BigDecimal或者用整型,整型地方法適合於貨幣精度已知的情況,比如12.11+1.10轉成1211+110計算,最後再/100即可
 * @author 秋雨
 * 修改歷史 
 *  序號------原因------修改人---日期---
 *   1.                               
 *   2.                                
 
*/ public class DoubleTool implements Serializable { private static final long serialVersionUID = -3345205828566485102L; //預設除法運算精度 private static final Integer DEF_DIV_SCALE = 2; /** * 提供精確的加法運算。 * @param value1 被加數 * @param value2 加數 * @return 兩個引數的和 */ public
static Double add(Double value1, Double value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1)); BigDecimal b2 = new BigDecimal(Double.toString(value2)); return b1.add(b2).doubleValue(); } /** * 提供精確的減法運算。 * @param value1 被減數 * @param value2 減數 *
@return 兩個引數的差 */ public static double sub(Double value1, Double value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1)); BigDecimal b2 = new BigDecimal(Double.toString(value2)); return b1.subtract(b2).doubleValue(); } /** * 提供精確的乘法運算。 * @param value1 被乘數 * @param value2 乘數 * @return 兩個引數的積 */ public static Double mul(Double value1, Double value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1)); BigDecimal b2 = new BigDecimal(Double.toString(value2)); return b1.multiply(b2).doubleValue(); } /** * 提供(相對)精確的除法運算,當發生除不盡的情況時, 精確到小數點以後10位,以後的數字四捨五入。 * @param dividend 被除數 * @param divisor 除數 * @return 兩個引數的商 */ public static Double divide(Double dividend, Double divisor) { return divide(dividend, divisor, DEF_DIV_SCALE); } /** * 提供(相對)精確的除法運算。 當發生除不盡的情況時,由scale引數指定精度,以後的數字四捨五入。 * @param dividend 被除數 * @param divisor 除數 * @param scale 表示表示需要精確到小數點以後幾位。 * @return 兩個引數的商 */ public static Double divide(Double dividend, Double divisor, Integer scale) { if (scale < 0) { throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal(Double.toString(dividend)); BigDecimal b2 = new BigDecimal(Double.toString(divisor)); return b1.divide(b2, scale,RoundingMode.HALF_UP).doubleValue(); } /** * 提供指定數值的(精確)小數位四捨五入處理。 * @param value 需要四捨五入的數字 * @param scale 小數點後保留幾位 * @return 四捨五入後的結果 */ public static double round(double value,int scale){ if(scale<0){ throw new IllegalArgumentException("The scale must be a positive integer or zero"); } BigDecimal b = new BigDecimal(Double.toString(value)); BigDecimal one = new BigDecimal("1"); return b.divide(one,scale, RoundingMode.HALF_UP).doubleValue(); } }