`
yznxing
  • 浏览: 370458 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

BigDecimal带精度的运算

    博客分类:
  • java
阅读更多

 

     之前提到过在商业运算中要使用BigDecimal来进行相关的钱的运算(java中关于浮点运算需要注意的 ),可是实际使用中,简单的用BigDecimal还是出现了一些小问题。

 

        BigDecimal a = new BigDecimal(998.01);
        BigDecimal b=new BigDecimal("100");
        System.out.println(a.multiply(b));
        
        BigDecimal aa = new BigDecimal(135.95);
        BigDecimal bb=new BigDecimal("100");
        System.out.println(aa.multiply(bb));
        
        
        BigDecimal test = new BigDecimal(4.015);
        BigDecimal test1 = new BigDecimal(100);
        System.out.println(test.multiply(test1));
 

输出结果为:

 

99800.999999999999090505298227071762084960937500
13594.99999999999886313162278383970260620117187500
401.49999999999996802557689079549163579940795898437500

 

   出现这种情况的原因就是没有使用BigDecimal的精度。不罗嗦了,直接写上使用BigDecimal的带精度的运算。

 

   比较简单,看代码:

 

 

BigDecimal aa = new BigDecimal(135.95);
BigDecimal bb=new BigDecimal("100");
BigDecimal result=aa.multiply(bb);
System.out.println(result.setScale(2,BigDecimal.ROUND_HALF_EVEN));
 

    此时的输出结果为:

 

13595.00
 

    最主要的是运用了:

 

 

result.setScale(2,BigDecimal.ROUND_HALF_EVEN)

 

    看一下BigDecimal的setScale的api

 

 

BigDecimal的API 写道
可以通过两种类型的操作来处理 BigDecimal 的标度:标度/舍入操作和小数点移动操作。标度/舍入操作(setScale 和 round)返回 BigDecimal,其值近似地(或精确地)等于操作数的值,但是其标度或精度是指定的值;即:它们会增加或减少对其值具有最小影响的存储数的精度。小数点移动操作(movePointLeft 和 movePointRight)返回从操作数创建的 BigDecimal,创建的方法是按指定方向将小数点移动一个指定距离。

 

 

setScale

public BigDecimal setScale(int newScale,
                           int roundingMode)
返回一个 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,
以维护其总值。如果该操作减少标度,则非标度值必须被除(而不是乘),并且该值可以更改;在这种情况下,将指定的
舍入模式应用到除法中。
注意,由于 BigDecimal 对象是不可变的,此方法的调用不会 导致初始对象被修改,
这与使用名为 setX 变异字段 X 方法的常规约定相反。相反,setScale 返回具有适当标度的对象;
返回的对象不一定是新分配的。

相对于此遗留方法,应优先使用新的 setScale(int, RoundingMode) 方法。

参数:
newScale - 要返回的 BigDecimal 值的标度。
roundingMode - 要应用的舍入模式。
返回:
一个 BigDecimal,其标度为指定值,其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。

RoundingMode的API

 

 

枚举常量摘要
CEILING  
          向正无限大方向舍入的舍入模式。
DOWN  
          向零方向舍入的舍入模式。
FLOOR  
          向负无限大方向舍入的舍入模式。
HALF_DOWN  
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。
HALF_EVEN  
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。
HALF_UP  
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。
UNNECESSARY  
          用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。
UP  
          远离零方向舍入的舍入模式。

 

 

  看完这些前面那个:

 

result.setScale(2,BigDecimal.ROUND_HALF_EVEN)

 

   的意思就是,将这个BigDecimal小数点后保留2位,四舍五入的方式为向最接近数字方向舍入的舍入 模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

 

    ok,记录完毕,看来以后要用bigDecimal还必须要用它这个scale的功能来保证精度,不然还是跟double一样会出现悲剧!

 

 

 

 

 

 

5
4
分享到:
评论
5 楼 xujishen 2016-09-22  
新入职 写道
还是没很明白~~这个BigDecimal.ROUND_HALF_EVEN的意思,感觉像文字游戏似的...语文不好啊

----------
even的意思就是  四舍六如 逢 五 上双: .4 以下肯定舍, .6 以上肯定入.  .5 往偶数那个方向舍入.
所以 3.5 和 4.5 都会舍入到 偶数 4  上面!
4 楼 jinianjun 2015-07-26  
楼主请看看chenem2000同学的回复。真实问题被你掩盖了。
3 楼 Ripin_Yan 2015-04-30  
楼主有点小疑问,BigDecimal.ROUND_HALF_EVEN方式可不是四舍五入,比如8.15,scale=1,那么结果就是8.2;但是8.25运算后还是8.2。四舍五入的应该是BigDecimal.ROUND_HALF_UP
2 楼 chenem2000 2011-04-13  
1.BigDecimal a = new BigDecimal(998.01);  
这样用double 构造BigDecimal是不精确的,因为double在计算机的表示本身就是不精确的。其实在java文档里的这个构造方法也提到:
Notes:

The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.
The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.
When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.

所以应该用string去构造浮点数。
BigDecimal a = new BigDecimal("998.01"); 
BigDecimal b=new BigDecimal("100"); 
System.out.println(a.multiply(b));
这样的结果就是99801.00。
当然我们仍然可以设定精度,特别是在除法的情况下。
1 楼 新入职 2010-08-17  
还是没很明白~~这个BigDecimal.ROUND_HALF_EVEN的意思,感觉像文字游戏似的...语文不好啊

相关推荐

    BigDecimal 加减乘除运算

    Java中BigInteger的数学运算,BigDecimal 加减乘除运算,Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大...

    Java中BigDecimal的基本运算(详解)

    Java中的BigDecimal是一种高精度的数据类型,它可以用来表示非常大的整数和小数,提供了丰富的数学运算功能。下面我们将对Java中BigDecimal的基本运算进行详细的介绍。 构造方法 BigDecimal有四种构造方法,但是...

    高精度JSBigDecimal运算

    `BigDecimal`类在Java等其他语言中是专门用来处理高精度十进制数的,它提供了丰富的算术运算方法,确保计算结果的精确性。在JavaScript中,虽然没有内置的`BigDecimal`类,但开发者可以通过第三方库来实现类似的功能...

    BigDecimal基本运算介绍

    `BigDecimal` 类是 Java 中用于高精度浮点数计算的关键工具,主要解决 `float` 和 `double` 类型在处理货币、财务等需要精确计算场景时存在的精度问题。`BigDecimal` 的运算方式与基本数据类型有所不同,因为它涉及...

    javascript版BigDecimal类库

    为了解决这个问题,开发者们引入了`BigDecimal`类库的概念,它在Java中被广泛使用,用于进行高精度的算术运算。本文将详细介绍JavaScript版的`BigDecimal`类库,以及如何在JavaScript环境中实现精确计算。 ...

    ArithmeticUtils-高精度数学运算.pdf

    通过封装这些方法,ArithmeticUtils简化了在Java程序中进行高精度运算的过程。 该工具类支持通过方法参数控制运算的精度,包括: 1. 提供精确的加法运算:通过两个参数(被加数和加数)进行加法运算,可以返回加法...

    BigDecimal类

    BigDecimal 类是 Java 中的一种数值类型,主要用于处理超过 16 位有效数字的数值运算。该类提供了多种构造器和方法,用于创建和操作 BigDecimal 对象。 构造器 BigDecimal 类提供了四种构造器,用于创建不同的 ...

    BigDecimal.js.zip

    这个库提供了一个名为`BigDecimal`的数据类型,用于实现大数运算,确保结果的精度不受损失。 "BigDecimal.js.zip"是一个压缩包,其中包含了"BigDecimal-all-last.min.js"文件。这个文件是BigDecimal.js库的最小化...

    Java中BigDecimal精度和相等比较的坑

    在Java编程中,`BigDecimal` 类是用来处理高精度、任意精度的十进制数的,尤其适用于财务和货币计算,因为它能确保计算结果的精确性。`float` 和 `double` 类型虽然在科学计算和工程计算中广泛使用,但它们无法提供...

    使用BigDecimal进行精确运算(实现加减乘除运算)

    BigDecimal是Java中用于进行高精度、精确浮点数运算的类,它解决了浮点数在二进制表示下无法精确表示所有十进制数的问题。在计算机科学中,由于浮点数(如float和double)是以二进制小数的形式存储,某些十进制数值...

    Java BigDecimal使用及基本运算(推荐)

    BigDecimal 类在 Java 中是用于处理高精度和大数值计算的,它确保了在计算过程中不会因为浮点数的精度问题而导致结果错误。由于 double 和 float 类型在处理大数或需要绝对精确计算的场景下存在精度损失,因此 ...

    BigDecimal使用

    3. 精确的加法运算:使用 BigDecimal 的 add 方法可以进行精确的加法运算,例如将两个 BigDecimal 对象相加并返回结果。 4. 精确的减法运算:使用 BigDecimal 的 subtract 方法可以进行精确的减法运算,例如将两个 ...

    BigDecimal工具类.docx

    BigDecimal工具类是Java中用于高精确处理常用数学运算的工具类。该工具类提供了多种精确的数学运算方法,包括加法、减法、乘法和除法等。 在BigDecimal工具类中,我们可以看到多个重载的方法,例如add方法和sub方法...

    BigDecimal加减乘除计算

    BigDecimal 类在 Java 中被设计用来处理高精度的浮点数运算,主要应用于财务、金融等领域,因为这些场景中对精度要求非常高。BigDecimal 提供了加法(add())、减法(subtract())、乘法(multiply())和除法...

    Java中使用BigDecimal进行精确运算

    为了解决这个问题,Java提供了`java.math.BigDecimal`类,它允许进行任意精度的十进制运算,确保了计算的准确性。BigDecimal类通过存储一个任意长度的非标度值和一个表示小数点位置的整数来实现精确的浮点数表示。 ...

    DecimalFormat精度解决,商业运算精度问题

    为了解决这一问题,Java提供了`BigDecimal`类,这是一个可以用来进行任意精度定点数运算的类。它能够提供对非常大的数字以及需要高度精确的计算的支持,非常适合用于财务和商业计算场景。 ### `BigDecimal`类的基本...

    BigDecimal向Double转换

    在Java编程语言中,BigDecimal是一种用于处理高精度数值的数据类型,尤其适用于金融计算等领域,因为它可以提供不受限的小数位数精度以及精确的数学运算能力。然而,在某些情况下,我们可能需要将BigDecimal类型的值...

    bigdecimal

    本文将深入探讨 `BigDecimal` 类的基本概念、特点以及如何使用它来进行精确的算术运算。 #### 一、基本概念 `BigDecimal` 类提供了一种可以进行任意精度定点数算术的方法。这意味着它可以存储一个数值的任意小数...

    BigDecimal-CPP-master.zip

    BigDecimal类提供了一种机制,可以进行任意精度的算术运算,而不会因为二进制浮点数的局限性而丢失精度。它通过存储浮点数的整数部分和小数部分,以及小数部分的位数来确保精度。 在"BigDecimal-CPP-master"这个...

    Java中使用BigDecimal进行浮点数运算

    为了解决这个问题,Java提供了`java.math.BigDecimal`类,它能够进行任意精度的十进制算术运算。`BigDecimal`对象代表一个不可变的、任意精度的有符号十进制数。这个类提供了一套丰富的算术、比较、格式化以及其他...

Global site tag (gtag.js) - Google Analytics