java+浮点数加减_Java中的浮点数-科学计数法-加减乘除

上次,提到“元转分”这个浮点数问题,boss倾向于手动把1.23元这种格式,转换成123分。      但实际上,浮点数很容易遇到精度问题。      比如,System.out.println(4.015 * 1000);结果就不会是4015。      以前,总结的元转分的问题,没能考虑到所有的场景,今天补充点上次遗漏的。      -5.09,如果金额是负数,应该是-500-9=-509,而不是-500+9=-441,这是上次的一个超级bug。      另外,需要还有一个超级bug,“1045189788”转换成double类型的元时,结果变成了1.04。      debug了好久,才发现以前代码的漏洞。      1045189788这种比较大的浮点数,在传递过程中,是“科学计数法”表示的,类似“1.04E”,   所以,最后转换出了问题。      其实,我一直不建议boss采用这种人工截取计算的方式,需要考虑的场景太复杂,建议使用JDK内置的BigDecimal。      经过实践,发现很不错。      可以用double、string等多种原始类型,构造BigDecimal,再进行四则运算。      使用BigDecimal的关键是,控制“标度”即“精度”,scale。      算术运算结果的首选标度  运算 结果的首选标度  加 max(addend.scale(), augend.scale())  减 max(minuend.scale(), subtrahend.scale())  乘 multiplier.scale() + multiplicand.scale()  除 dividend.scale() - divisor.scale()    下面这个工具类,是从网上copy的,还是非常有价值的。      import java.math.BigDecimal; /**  * 消除加减乘除的精度,解决Float与Double类型进度不准确的问题.  */ public class DoubleUtil { /** * 加法运算 *  * @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(); } /** * 除法运算 *  * @param v1 *            被除数 * @param v2 *            除数 * @return 商 */ public static double div(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); return b1.divide(b2).doubleValue(); } /** * 除法运算 *  * @param v1 *            被除数 * @param v2 *            除数 * @return 商和余数 */ public static BigDecimal[] divideAndRemainder(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); BigDecimal[] arr = b1.divideAndRemainder(b2); return arr; } /** * 求商(向下舍入) *  * @param v1 * @param v2 * @return */ public static BigDecimal divideToIntegralValue(double v1, double v2) { BigDecimal b1 = new BigDecimal(Double.toString(v1)); BigDecimal b2 = new BigDecimal(Double.toString(v2)); System.out.println("------------"); return b1.divideToIntegralValue(b2); } public static void main(String[] args) { testUnPrecision(); System.out.println("----------使用BigDecimal消除精度影响------------\n" + DoubleUtil.add(0.05, 0.01)); System.out.println(DoubleUtil.sub(1.0, 0.54)); System.out.println(DoubleUtil.mul(4.015, 1000)); System.out.println(DoubleUtil.div(12.3, 10)); // 得到商和余数 BigDecimal[] arr = DoubleUtil.divideAndRemainder(12.3, 10); System.out.println("得到商和余数"); for (BigDecimal bigDecimal : arr) { System.out.println(bigDecimal); } System.out.println(DoubleUtil.divideToIntegralValue(4.5, 2)); } /** * 不准确问题示例 */ private static void testUnPrecision() { System.out.println("--------Java自身的Double类型有精度损失----------"); System.out.println(0.05 + 0.01); System.out.println(1.0 - 0.54); System.out.println(4.015 * 1000); System.out.println(12.3 / 100); } }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
唔,其实里面就是一个工具类,加减乘除、保留两位小数。一共5个方法。。。emmmm.....为啥分这么高呢。因为宝宝想分想疯了。 附代码,有土豪就打赏打赏,没土豪的直接拿去使吧。 package cn.cisdom.base.utils; import java.math.BigDecimal; import java.text.DecimalFormat; public class Calculation { public static final DecimalFormat df = new DecimalFormat("######0.00"); /** * @methodName format2point * @desc 保留两位小数点 * @param value * @return java.lang.String * @author xm * @create 2018/6/7 12:03 **/ public static String format2point(Number value) { return df.format(value); } public static Double add(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.add(b2).doubleValue(); } /** * 提供精确的减法运算。 * * @param value1 * 减数 * @param value2 * 被减数 * @return 两个参数的差 */ public static Double sub(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.subtract(b2).doubleValue(); } /** * 提供精确的乘法运算。 * * @param value1 * 被乘数 * @param value2 * 乘数 * @return 两个参数的积 */ public static Double mul(Number value1, Number value2) { BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.multiply(b2).doubleValue(); } /** * 提供精确的除法运算。 * * @param value1 * 除数 * @param value2 * 被除数 * @return 除数/被除数 */ public static Double div(Number value1, Number value2) { //MathContext mc = new MathContext(2, RoundingMode.HALF_DOWN);//精度为2,舍入模式为大于0.5进1,否则舍弃 BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1.divide(b2).doubleValue(); } public static void main(String[] args) { Double aDouble=Calculation.add(56.9, 1.67); System.out.println(aDouble); Double bDouble=Calculation.sub(99.2,aDouble); System.out.println(bDouble); } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值