近期经常接触支付相关的功能,在开发及测试过程中,开始金额都使用的是double类型,而近期新进的需求存在支付时打折的情况,也就是会出现如 1.23元的情况,那么这时候问题来了,如果是直接使用1.23进行支付都是不存在问题的。而偏偏在支付前通常需要一些计算。我们的系统支持会员余额与三方支付微信、支付宝)同时进行,比如一笔待支付的订单是12.8员,其中用户有5块钱的会员余额,剩下的7.8元通过三方支付进行这里使用微信吧),那么就涉及到double减法,同时微信支付时需要将元转为分,就是7.8×100,这又涉及到了乘法,此时就出现了double精度计算的问题。如下例子:
double a = 12.3d; double b = 5d; System.out.printlna-b); // 7.300000000000001 double c= 1.13d; System.out.printlnc * 100); // 112.99999999999999
上面的计算存在了精度问题,这样计算还需要进行四舍五入,比较麻烦。因此我们想到使用BigDecimal来实现小数的计算。最简单的加减乘除运算如下,希望可以帮到遇到同样问题的童鞋:
package com.blacksonny.utils; import java.math.BigDecimal; /** * Created by kk on 2015/12/28.<br> */ public class NumericUtils { /** * double 加运算 * * @param a * @param b * @return */ public static double adddouble a, double b) { BigDecimal b1 = new BigDecimalDouble.toStringa)); BigDecimal b2 = new BigDecimalDouble.toStringb)); return b1.addb2).doubleValue); } /** * float 加运算 * * @param a * @param b * @return */ public static float addfloat a, float b) { BigDecimal b1 = new BigDecimalDouble.toStringa)); BigDecimal b2 = new BigDecimalDouble.toStringb)); return b1.addb2).floatValue); } /** * double 减运算 * * @param a * @param b * @return */ public static double subtractdouble a, double b) { BigDecimal b1 = new BigDecimalDouble.toStringa)); BigDecimal b2 = new BigDecimalDouble.toStringb)); return b1.subtractb2).doubleValue); } /** * float 减运算 * * @param a * @param b * @return */ public static float subtractfloat a, float b) { BigDecimal b1 = new BigDecimalDouble.toStringa)); BigDecimal b2 = new BigDecimalDouble.toStringb)); return b1.subtractb2).floatValue); } /** * double 乘运算 * * @param a * @param b * @return */ public static double multiplydouble a, double b) { BigDecimal b1 = new BigDecimalDouble.toStringa)); BigDecimal b2 = new BigDecimalDouble.toStringb)); return b1.multiplyb2).doubleValue); } /** * float 乘运算 * * @param a * @param b * @return */ public static float multiplyfloat a, float b) { BigDecimal b1 = new BigDecimalDouble.toStringa)); BigDecimal b2 = new BigDecimalDouble.toStringb)); return b1.multiplyb2).floatValue); } /** * double 除运算 * * @param a * @param b * @return */ public static double dividedouble a, double b) { BigDecimal b1 = new BigDecimalDouble.toStringa)); BigDecimal b2 = new BigDecimalDouble.toStringb)); return b1.divideb2).doubleValue); } /** * float 除运算 * * @param a * @param b * @return */ public static float dividefloat a, float b) { BigDecimal b1 = new BigDecimalDouble.toStringa)); BigDecimal b2 = new BigDecimalDouble.toStringb)); return b1.divideb2).floatValue); } }
另外在javascript中也存在精度计算的问题,没有什么好的方法,计算时使用parseFloat先转换,再取精度,写法为 parseFloatxx.xxx).toFixed2); //2表示取两位小数。
同时对于常用的需要将一个double转为BigDecimal时,应该使用BigDecimal.valueOf0.1), 或者new BigDecimal”0.1″), 而不要直接将double类型作为构造方法的入参传入,这种写法有精度的问题。