关于前后端精度问题求解

起因是在前端计算金额的时候,导致和总金额不等:

1.计算:"246409.2", "328545.6", "164272.8", "82136.4"的和,发现他的结果是
  System.out.println((new BigDecimal(246409.2+328545.6+164272.8+82136.4)));
  //输出结果:
  821364.000000000116415321826934814453125

跟想象的不一样,其实相当然以为是821364.0

2.又想了一种计算方式:
System.out.println((246409.2+328545.6+164272.8+82136.4));
//输出结果
821364.0000000001
3.再换一种(这里想的是前端直接+的话可能是字符串拼接了,所以×1)
System.out.println((246409.2*1+328545.6*1+164272.8*1+82136.4));
//输出结果
821364.0000000001
4.又试了一种发现这个计算合理那就是BigDecimal类
      String [] numbers = {"246409.2", "328545.6", "164272.8", "82136.4"};
        //求和
        BigDecimal sum = BigDecimal.ZERO;
        for (String number : numbers) {
            sum = sum.add(new BigDecimal(number));
        }
        System.out.println("总和是:" + sum);
        //输出结果是
        总和是:821364.0

这些都是由于精度问题导致的,查了一下,在做运算的时候前端的话会,(java也是二进制计算的,具体的话懒得知道)

IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现),js则是64位

总之就是转成2进制再计算,比较精确,一般科学、数学需要用它比较合适,向我们正常计算。尤其这个算金额的时候大可不必

5.下面给出自己按照小数点位数的计算精度问题:
 public static void main(String[] args) {
        String [] numbers = {"246409.2", "328545.60", "164272.8", "82136.4"};
        round(numbers);
    }

    //用于精度问题求和的通用方法
    public static void round(String[]numbers) {
        //定义一个最长的小数位数
        int maxLen = 0;
        //求和
        BigDecimal sum = BigDecimal.ZERO;
        // 遍历这个数组
        for (String number : numbers) {
            //取小数点后几位找最长的是多少位
            int len = number.indexOf(".");
            if (len != -1) {
                len = number.substring(len + 1).length();
            }
            //比较这组数的最长的精度的最大值
            if (len > maxLen) {
                maxLen = len;
            }
            sum = sum.add(new BigDecimal(number));
        }
        //将这组数据求和再取最大长度的小数位数
        System.out.println(sum.setScale(maxLen, BigDecimal.ROUND_HALF_UP));
    }
//输出结果
821364.00

这种方法就是找出这组数据小数点最长的位数给求和结果取保留位数,看BigDecimal的底层, 脑袋大,不想看了,反正我试了也是给定几位,计算之后也是按照位数最长的来的,等待大神有缘人讲讲吧

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值