java实现加减乘除法的精确运算

论坛 期权论坛 编程之家     
选择匿名的用户   2021-5-21 16:58   855   0

首先来看一个简单的例子:

public class TestK {

 public static void main(String[] args) {
  double params1 = 1.88d;
  double params2= 1.89d;
  System.out.println(params1+params2);
 }
}

肯定有许多人第一反应,结果当然是3.77,事实真的是这样么?答案是NO,发现程序已运行,输出结果:3.7699999999999996,咦,这是什么情况,难道计算机出现问题了?
原因就在于:计算机里面数的计算都是二进制计算的,我们其实输入的十进制数,有些十进制数转换成二进制是可以精确转换,而有些转换则不是精确转换,得到的是一个最靠近它的数,所以这里面就存在一个误差。另外,如果浮点数不进行计算时,在十进制里面浮点数能正确显示,如果浮点数参与了计算,那么浮点数二进制与十进制间的转换过程就会变得不可而知,变得不可逆。

那我们怎么才能得到正确的结果呢,请看下面的方法

/**
  * 加法
  */
 public static Double add(Double parms1,Double param2){
  if(parms1 == null){
   parms1 = 0D;
  }
  if(param2 == null){
   param2 = 0D;
  }
  return new BigDecimal(String.valueOf(parms1)).add(new BigDecimal(String.valueOf(param2))).doubleValue();
 }

同理,减法、乘除法同样存在这样的问题。本人写了一个方法类,不喜勿喷

/**
 * 加减法精确计算类
 */
public class CalculationUtil {

 private CalculationUtil(){}
 
 /**
  * 加法
  */
 public static Double add(Double parms1,Double param2){
  if(parms1 == null){
   parms1 = 0D;
  }
  if(param2 == null){
   param2 = 0D;
  }
  return new BigDecimal(String.valueOf(parms1)).add(new BigDecimal(String.valueOf(param2))).doubleValue();
 }
 
 /**
  * 减法
  */
 public static Double subtract(Double parms1,Double param2){
  if(parms1 == null){
   parms1 = 0D;
  }
  if(param2 == null){
   param2 = 0D;
  }
  return new BigDecimal(String.valueOf(parms1)).subtract(new BigDecimal(String.valueOf(param2))).doubleValue();
 }
 
 /**
  * 乘法
  */
 public static Double multiply(Double parms1,Double param2){
  if(parms1 == null){
   parms1 = 0D;
  }
  if(param2 == null){
   param2 = 0D;
  }
  return new BigDecimal(String.valueOf(parms1)).multiply(new BigDecimal(String.valueOf(param2))).doubleValue();
 }
 
 /**
  * 除法
  * digit:小数位数
  * roundType:四舍五入或者向下取整
  */
 public static Double divide(Double parms1,Double param2,int digit,int roundType){
  if(parms1 == null){
   parms1 = 0D;
  }
  if(param2 == null || param2 == 0){
   return 0D;
  }
  return new BigDecimal(String.valueOf(parms1)).divide(new BigDecimal(String.valueOf(param2)),digit,roundType).doubleValue();
 }
 
 /**
  * 四舍五入
  * @param parms1
  * @return
  */
 public static Double scale(Double parms1,int digit){
  if(parms1 == null){
   parms1 = 0D;
  }
  return new BigDecimal(String.valueOf(parms1)).setScale(digit,BigDecimal.ROUND_HALF_UP).doubleValue();//四舍五入,2.35变成2.4
 }
}


分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP