java.math.BigDecimal,关于金额的精确计算

今天无意中看以前的东东,发现两个double类型的数直接相加时,得到的结果不对

 

import java.math.BigDecimal;
public class TestDouble {
  public static void main(String[] args) {
  double d1 = 0.01;
  double d2 = 0.05;
  String s1 = "8.0";
  String s2 = "3.0";
  System.out.println(d1+d2);//结果为0.060000000000000005,其中缘由还不明白,请大侠们多多指教

//需要转换成BigDecimal 类型可以得到正确结果
  BigDecimal bd1 = new BigDecimal(d1+"");  
  BigDecimal bd2 = new BigDecimal(d2+"");
  System.out.println(
   bd1.add(bd2).doubleValue());//BigDecimal 类型加
  System.out.println(bd1.subtract(bd2).doubleValue());//BigDecimal 类型减
  BigDecimal bd3 = new BigDecimal(s1);
  BigDecimal bd4 = new BigDecimal(s2);
  
  System.out.println(
    bd3.multiply(bd4).doubleValue());//BigDecimal 类型乘
  System.out.println(
   bd3.divide(bd4,6,BigDecimal.ROUND_HALF_UP).doubleValue());//BigDecimal 类型除//

//ROUND_HALF_UP: 遇到.5的情况时往上进,例: 1.5 ->;2
 //ROUND_HALF_DOWN : 遇到.5的情况时往下进,例: 1.5 ->;1
 }

}

 

--------------------------------------------------------------

BigDecimal类还有一些其他的参数,是在网上收索到的,如下:

 

其他参数说明

 

ROUND_CEILING    
  如果   BigDecimal   是正的,则做   ROUND_UP   操作;如果为负,则做   ROUND_DOWN   操作。    
  ROUND_DOWN    
  从不在舍弃(即截断)的小数之前增加数字。    
  ROUND_FLOOR    
  如果   BigDecimal   为正,则作   ROUND_UP   ;如果为负,则作   ROUND_DOWN   。    
  ROUND_HALF_DOWN    
  若舍弃部分>   .5,则作   ROUND_UP;否则,作   ROUND_DOWN   。    
  ROUND_HALF_EVEN    
  如果舍弃部分左边的数字为奇数,则作   ROUND_HALF_UP   ;如果它为偶数,则作   ROUND_HALF_DOWN   。    
  ROUND_HALF_UP    
  若舍弃部分>=.5,则作   ROUND_UP   ;否则,作   ROUND_DOWN   。    
  ROUND_UNNECESSARY    
  该“伪舍入模式”实际是指明所要求的操作必须是精确的,,因此不需要舍入操作。    
  ROUND_UP    
  总是在非   0   舍弃小数(即截断)之前增加数字。     

 

---------------------------------------------------------------------

注: 也是在网上看到的有人说
   BigDecimal只有构造函数为String时才能真正做到精确计算,这方面用BigDecimal.valueOf是不行的,

有人建议把需要精确的数变成一个bigInteger,没有测试,据说不能完全解决精度问题。

 

-----------------------------------------------------------------------------

BigDecimal性能的问题

http://users.belgacombusiness.net/arci/

看看这个,另一个BigDecimal实现,据称比java.math.BigDecimal快

Java的`BigDecimal`是用于高精度计算的类。它提供了大数的精确计算,适用于处理需要精确小数位数的情况,例如金融计算或科学计算。 `BigDecimal`可以处理任意精度的数值,并提供了各种运算方法,如加法、减法、乘法和除法等。它还支持舍入模式和比较操作。 使用`BigDecimal`时需要注意以下几点: 1. `BigDecimal`对象是不可变的,每次进行运算都会返回一个新的`BigDecimal`对象。 2. 构造一个`BigDecimal`对象时,可以使用字符串、整型、浮点型等作为参数。 3. 进行除法运算时,需要指定除法运算规则和舍入模式。 4. 要比较两个`BigDecimal`对象的大小,可以使用`compareTo()`方法。 下面是一个简单的示例代码,演示了如何使用`BigDecimal`进行精确计算: ```java import java.math.BigDecimal; public class BigDecimalExample { public static void main(String[] args) { BigDecimal num1 = new BigDecimal("10.5"); BigDecimal num2 = new BigDecimal("5.2"); // 加法 BigDecimal sum = num1.add(num2); System.out.println("Sum: " + sum); // 减法 BigDecimal difference = num1.subtract(num2); System.out.println("Difference: " + difference); // 乘法 BigDecimal product = num1.multiply(num2); System.out.println("Product: " + product); // 除法 BigDecimal quotient = num1.divide(num2, 2, BigDecimal.ROUND_HALF_UP); System.out.println("Quotient: " + quotient); // 比较大小 int comparison = num1.compareTo(num2); if (comparison > 0) { System.out.println("num1 is greater than num2"); } else if (comparison < 0) { System.out.println("num1 is less than num2"); } else { System.out.println("num1 is equal to num2"); } } } ``` 希望这个简单的解释和示例能帮到你!如果有任何其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值