package com.shopping.test;import java.math.BigDecimal;/** * 精确的浮点运算 * 为什么要使用BigDecimal类型呢? * BigDecimal可以进行超过16位有效位的数值的准确运算,而我们所熟知的浮点型float的精度为6-7位有效数字,Double类型则为15-16位有效数字。 * 这不是关键,浮点型变量在进行计算的时候会出现丢失精度的问题,所以我们为了保证数据的准确性,需要用到BigDecimal去进行高精度的运算。 */public class OperationUtil { private static final int DEF_DIV_SCALE=10;//默认除法运算精度 private OperationUtil(){ } /** * 精确的加法运算 * @param v1 被加数 * @param v2 加数 * @return 两个参数的和 */ public static double add(double v1 ,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.add(b2).doubleValue(); } /** * 精确的减法运算 * @param v1 被减数 * @param v2 减数 * @return 两个参数的差 */ public static double sub(double v1 ,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.subtract(b2).doubleValue(); } /** * 精确的乘法运算 * @param v1 被乘数 * @param v2 乘数 * @return 两个参数的积 */ public static double mul(double v1 ,double v2){ BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.multiply(b2).doubleValue(); } /** * 相对精确的除法运算 * 当除不尽时候精确到小数点后10位,以后的数字四舍五入 * @param v1 被除数 * @param v2 除数 * @return 两个参数的商 */ public static double div(double v1 ,double v2){ return div(v1, v2,DEF_DIV_SCALE); } /** * 提供精确的除法运算 * 当除不尽时候精确到小数点后 scale 位,以后的数字四舍五入 * @param v1 被除数 * @param v2 除数 * @param scale 精确到小数点后几位 * @return 两个参数的商 */ public static double div(double v1 ,double v2,int scale){ if (scale<0){ throw new IllegalArgumentException("The scale must be a positive or zero "); } BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b2.divide(b1,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } /** * 提供精确到小数位的数字四舍五入 * @param v 需要四舍五入的数字 * @param scale 小数点后保留几位 * @return 四舍五入后的结果 */ public static double round(double v ,int scale){ if (scale<0){ throw new IllegalArgumentException("The scale must be a positive or zero "); } BigDecimal b = new BigDecimal(Double.toString(v)); BigDecimal one = new BigDecimal(1); return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue(); } public static void main(String[] args){ System.out.println(OperationUtil.round (3.3334111,3)); System.out.println(OperationUtil.round (3.3335111,3)); }}
当然不同的场景所需要的算法不一样