zoukankan      html  css  js  c++  java
  • java精确运算

    public class ArithUtil {
        /**
         * 加法
         * @param 
         * @return double
         * @throws Exception
         * @author zhangyn
         * @date 2017年6月7日 下午6:33:30
         */
        public static double add(double value1, double value2) {
            BigDecimal b1 = new BigDecimal(Double.toString(value1));
            BigDecimal b2 = new BigDecimal(Double.toString(value2));
            return b1.add(b2).doubleValue();
        }
        
        /**
         * 减法
         * @param value1 减数
         * @param value2 被减数
         * @return  double
         * @throws  Exception
         * @author  zhangyn
         * @date    2017年6月9日 下午3:29:30
         */
        public static double sub(double value1,double value2){
            BigDecimal b1 = new BigDecimal(Double.toString(value1));
            BigDecimal b2 = new BigDecimal(Double.toString(value2));
            return b1.subtract(b2).doubleValue();
        }
        
        /**
         * 乘法
         * @param
         * @return double
         * @throws Exception
         * @author zhangyn
         * @date 2017年6月7日 下午6:33:49
         */
        public static double mul(double value1, double value2) {
            BigDecimal b1 = new BigDecimal(Double.toString(value1));
            BigDecimal b2 = new BigDecimal(Double.toString(value2));
            return b1.multiply(b2).doubleValue();
        }
        
         /**
         * 提供精确的除法运算方法div
         * @param value1 被除数
         * @param value2 除数
         * @param scale 精确范围,必须大于0
         * @return 两个参数的商
         * @throws IllegalAccessException
         */
        public static double div(double value1,double value2,int scale) throws IllegalAccessException{
            //如果精确范围小于0,抛出异常信息
            if(scale<0){         
                throw new IllegalAccessException("精确度不能小于0");
            }
            BigDecimal b1 = new BigDecimal(Double.toString(value1));
            BigDecimal b2 = new BigDecimal(Double.toString(value2));
            return b1.divide(b2, scale).doubleValue();    
        }
        
        /** 两个double比较或者金额比较,建议小数点后保留两位
          * @Description ArithUtil.java    
          * @param value1
          * @param value2
          * @return -1 是不相等 0:相等
          * @throws Exception                    
          * @author liz
          * @date 2017年6月28日下午4:22:34
         */
        public static int doubleCompare(String value1,String value2) throws Exception{
            if(GenericValidator.isBlankOrNull(value1) || GenericValidator.isBlankOrNull(value2)){
                return -1;
            }else{
                return new BigDecimal(value1).compareTo(new BigDecimal(value2));
            }
            
        }
        
        
        /**
         * 整数加法的精确运算
         * @param
         * @return  int
         * @throws  Exception
         * @author  zhangyn
         * @date    2017年6月26日 下午6:58:04
         */
        public static int addint(int value1, int value2) {
            BigDecimal b1 = new BigDecimal(String.valueOf(value1));
            BigDecimal b2 = new BigDecimal(String.valueOf(value2));
            return b1.add(b2).intValue();
        }
        
        /**
         * 整数减法的精确运算
         * @param value1 减数
         * @param value2 被减数
         * @return  int
         * @throws  Exception
         * @author  zhangyn
         * @date    2017年6月26日 下午6:59:27
         */
        public static int subint(int value1,int value2){
            BigDecimal b1 = new BigDecimal(String.valueOf(value1));
            BigDecimal b2 = new BigDecimal(String.valueOf(value2));
            return b1.subtract(b2).intValue();
        }
        
        /**
         * 整数乘法精确运算
         * @param
         * @return  int
         * @throws  Exception
         * @author  zhangyn
         * @date    2017年6月26日 下午7:01:58
         */
        public static int mulint(int value1, int value2) {
            BigDecimal b1 = new BigDecimal(String.valueOf(value1));
            BigDecimal b2 = new BigDecimal(String.valueOf(value2));
            return b1.multiply(b2).intValue();
        }
        
         /**
         * 整数除法精确运算
         * @param value1 被除数
         * @param value2 除数
         * @param scale 精确范围,必须大于0
         * @return 两个参数的商
         * @throws IllegalAccessException
         * @date    2017年6月26日 下午7:02:58
         */
        public static int divint(int value1,int value2,int scale) throws IllegalAccessException{
            //如果精确范围小于0,抛出异常信息
            if(scale<0){         
                throw new IllegalAccessException("精确度不能小于0");
            }
            BigDecimal b1 = new BigDecimal(String.valueOf(value1));
            BigDecimal b2 = new BigDecimal(String.valueOf(value2));
            return b1.divide(b2, scale).intValue();    
        }
    }
    View Code

     为什么不直接四则运算呢?换句话说计算机计算机为什么有精度损失呢?

    以下内容摘自百度百科@二进制

    大家知道的,计算机以二进制存储数据,精度损失就发生在十进制转二进制的时候

    计算机中的十进制小数转换二进制
    计算机中的十进制小数用二进制通常是用乘二取整法来获得的。
    比如0.65换算成二进制就是:
    0.65 × 2 = 1.3 取1,留下0.3继续乘二取整
    0.3 × 2 = 0.6 取0, 留下0.6继续乘二取整
    0.6 × 2 = 1.2 取1,留下0.2继续乘二取整
    0.2 × 2 = 0.4 取0, 留下0.4继续乘二取整
    0.4 × 2 = 0.8 取0, 留下0.8继续乘二取整
    0.8 × 2 = 1.6 取1, 留下0.6继续乘二取整
    0.6 × 2 = 1.2 取1,留下0.2继续乘二取整
    .......
    一直循环,直到达到精度限制才停止(所以,计算机保存的小数一般会有误差,所以在编程中,要想比较两个小数是否相等,只能比较某个精度范围内是否相等。)。这时,十进制的0.65,用二进制就可以表示为:01010011。
  • 相关阅读:
    [武汉集训] Cliquers
    [NOI2017] 泳池
    [NOWCODER7] 小睿睿的方案
    动态dp初探
    [WC2008] 游览计划
    插头dp初探
    最小斯坦纳树初探
    2020ccpc总结
    Finding Palindromes
    最长非严格上升子序列的思考 && CF 1437E Make It Increasing
  • 原文地址:https://www.cnblogs.com/yanan7890/p/7126480.html
Copyright © 2011-2022 走看看