zoukankan      html  css  js  c++  java
  • java中多个数字运算后值不对(失真)处理方法

    最近遇到一个bug ,在java里面计算两个数字相减,633011.20-31296.30

    得到的结果居然是601714.8999999999,丢失精度了,原来这是Java浮点运算的一个bug。

    解决方法:网上找到了一些解决办法,就是重新写了一些浮点运算的函数。
    下面就把这些方法摘录下来,以供遇到同样问题的朋友参考:

    简易计算器点击下载

    js中多个数字运算后值不对(失真)处理方法

    调用方法:

    public static void main(String[] args) throws Exception{
            System.out.println("加法未处理:0.05+0.01="+(0.05+0.01));
            System.out.println("加法已处理:0.05+0.01="+add(0.05,0.01));
            System.out.println("减法未处理:1.0-0.42="+(1.0-0.42));
            System.out.println("减法已处理:1.0-0.42="+sub(1.0,0.42));
            System.out.println("减法未处理:633011.20-31296.30="+(633011.20-31296.30));
            System.out.println("减法已处理:633011.20-31296.30="+sub(633011.20,31296.30));
            System.out.println("乘法未处理:4.015*10="+(4.015*100));
            System.out.println("乘法已处理:4.015*10="+mul(4.015,100));
            System.out.println("除法未处理:123.3/100="+(123.3/100));
            System.out.println("除法已处理:123.3/100="+division(123.3,100));
        }

    控制台输出效果:

    加法未处理:0.05+0.01=0.060000000000000005
    加法已处理:0.05+0.01=0.06
    减法未处理:1.0-0.42=0.5800000000000001
    减法已处理:1.0-0.42=0.58
    减法未处理:633011.20-31296.30=601714.8999999999
    减法已处理:633011.20-31296.30=601714.9
    乘法未处理:4.015*10=401.49999999999994
    乘法已处理:4.015*10=401.5
    除法未处理:123.3/100=1.2329999999999999
    除法已处理:123.3/100=1.23

    java程序代码

    1.加法运算

        /**
         * 计算两个值的加法运算
         * @param arg1
         * @param arg2
         * @return
         * @throws Exception
         */
        public static double add(double arg1,double arg2) throws Exception{
            String arg11 = arg1+"";
            String arg22 = arg2+"";
            int r1 = 0;
            int r2 = 0;
            int m = 0;
            try{
                r1=arg11.split("\.")[1].length();
            }catch(Exception e){
                r1=0;
            }
            try{
                r2=arg22.split("\.")[1].length();
            }catch(Exception e){
                r2=0;
            }
            m=(int) Math.pow(10,Math.max(r1,r2));
            
            return (arg1 * m + arg2 * m)/m;
        }

    2.减法运算

        /**
         * 计算两个值的减法运算
         * @param arg1
         * @param arg2
         * @return
         * @throws Exception
         */
        public static double sub(double arg1,double arg2) throws Exception{
            String arg11 = arg1+"";
            String arg22 = arg2+"";
            int r1 = 0;
            int r2 = 0;
            int m = 0;
            int n = 0;
            try{
                r1=arg11.split("\.")[1].length();
            }catch(Exception e){
                r1=0;
            }
            try{
                r2=arg22.split("\.")[1].length();
            }catch(Exception e){
                r2=0;
            }
            
            m = (int)Math.pow(10, Math.max(r1, r2));
            //last modify by deeka
            //动态控制精度长度
            n = (r1 >= r2) ? r1 : r2;
            double result = ((arg1 * m - arg2 * m) / m);
                    
            //BigDecimal.ROUND_HALF_UP表示四舍五入,BigDecimal.ROUND_HALF_DOWN也是五舍六入,BigDecimal.ROUND_UP表示进位处理(就是直接加1),BigDecimal.ROUND_DOWN表示直接去掉尾数。
            BigDecimal b = new BigDecimal(result);
            result = b.setScale(n, BigDecimal.ROUND_HALF_UP).doubleValue();
            return result;
        }

    3.乘法运算

        /**
         * 计算两个值的乘法运算
         * @param arg1
         * @param arg2
         * @return
         * @throws Exception
         */
        public static double mul(double arg1,double arg2) throws Exception{
            String arg11 = arg1+"";
            String arg22 = arg2+"";
            int m = 0;
            try{
                m+=arg11.split("\.")[1].length();
            }catch(Exception e){
                System.out.println("计算出错");
            }
            try{
                m+=arg22.split("\.")[1].length();
            }catch(Exception e){
                System.out.println("计算出错");
            }
            return Integer.parseInt(arg11.replace(".",""))*Integer.parseInt(arg22.replace(".",""))/Math.pow(10,m);
        }

    4.除法运算

        /**
         * 计算两个值的除法运算
         * @param arg1
         * @param arg2
         * @return
         * @throws Exception
         */
        public static double division(double arg1,double arg2) throws Exception{
            String arg11 = arg1+"";
            String arg22 = arg2+"";
            int t1 = 0;
            int t2 = 0;
            int r1 = 0;
            int r2 = 0;
            try{
                t1=arg11.split("\.")[1].length();
            }catch(Exception e){
                System.out.println("计算出错");
            }
            try{
                t2=arg22.split("\.")[1].length();
            }catch(Exception e){
                System.out.println("计算出错");
            }
            r1=Integer.parseInt(arg11.replace(".",""));
            r2=Integer.parseInt(arg22.replace(".",""));
            double result = ((float)r1/r2)*(Math.pow(10,t2-t1));
            //BigDecimal.ROUND_HALF_UP表示四舍五入,BigDecimal.ROUND_HALF_DOWN也是五舍六入,BigDecimal.ROUND_UP表示进位处理(就是直接加1),BigDecimal.ROUND_DOWN表示直接去掉尾数。
            BigDecimal b = new BigDecimal(result);
            result = b.setScale(t1 + t2, BigDecimal.ROUND_HALF_UP).doubleValue();
            return result;
        }
  • 相关阅读:
    oo第四次作业总结
    oo第三次博客总结
    oo第二次博客总结
    oo第一次博客总结
    leetcode155-最小栈
    leetcode141-环形链表
    leetcode278-第一个错误的版本
    leetcode118-杨辉三角
    LeetCode21-合并两个有序列表
    LeetCode27-移除元素
  • 原文地址:https://www.cnblogs.com/shuilangyizu/p/10044037.html
Copyright © 2011-2022 走看看