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

BigDecimal使用常见误区

阅读更多
BigDecimal.valueOf(0.03f)

最近工作中一个同事用到了上述用法,感觉会丢失精度,但也不是特别确定,于是把BigDecimal这块使用过程中踩过的坑稍微整理一下。

 

使用误区一:初始化

        System.out.println(new BigDecimal("0.03"));
        System.out.println(new BigDecimal(3));
        System.out.println(new BigDecimal(0.03));

        System.out.println(BigDecimal.valueOf(3L));
        System.out.println(BigDecimal.valueOf(0.03));
        System.out.println(BigDecimal.valueOf(0.03f));

 

上述你能准确说出运行结果么?

0.03
3
0.0299999999999999988897769753748434595763683319091796875
3
0.03
0.029999999329447746

 

原理分析

最常用的标准构造器为:

public BigDecimal(String val);

另一个也基本一致:   

public static BigDecimal valueOf(double val) {
        return new BigDecimal(Double.toString(val));
    }

其他构造器使用不小心的话就可能产生问题,这块后续对java中的数值类型精度方面做个细致的学习和整理。

BigDecimal.valueOf(0.03f)这个数值不符合预期是float转double的时候丢失精度了,跟BigDecimal无关。

 

 

使用误区二:比较

        BigDecimal a = new BigDecimal("1.23");
        BigDecimal b = new BigDecimal("1.230");
        System.out.println(a.equals(b)); //false

结果竟不是预期的true。

原理分析 

equals是比较内容,自然不一样。BigDecimal的比较要用compareTo

        System.out.println(a.compareTo(b)); //0表示相等

 

 

使用误区三:运算 

        BigDecimal c = new BigDecimal("1.23");
        BigDecimal d = new BigDecimal("1.23");
        c.add(d);
        System.out.println(c);

 结果是2,46么?

显然不是,仍然是1.23

 

原理分析

BigDecimal加减乘除最终都返回的是一个新的BigDecimal对象,c.add(d);虽然做了加法操作,但是c并没有保存加操作后的值,正确的用法应该是c=c.add(d)。

 

 

使用误区四:除不尽

 

        System.out.println(new BigDecimal("100").divide(new BigDecimal("12")));
 结果直接抛异常了。
异常 如下:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

 

原理分析

BigDecimal的除法要养成习惯去设置精度,以免出现无限循环小数而抛异常。

 

new BigDecimal("100").divide(new BigDecimal("12").setScale(2, BigDecimal.ROUND_HALF_DOWN)

 这样写对么?wrong,正确写法如下:

new BigDecimal("100").divide(new BigDecimal("12"),2, BigDecimal.ROUND_HALF_DOWN);

 

 

再思考 

        System.out.println(0.99999999f == 1f); //true
        System.out.println(0.99999999 == 1); //false
 

note:关于java数值精度(double、float、BigDecimal)这块后续再整理一次,如果不明白细节,很容易犯错误。

2
0
分享到:
评论
4 楼 welcomezhang 2016-06-20  
jiangchao89911 写道
使用误区四:除不尽,这样写似乎也不对啊
System.out.println(new BigDecimal("100").divide(new BigDecimal("12").setScale(2, BigDecimal.ROUND_HALF_DOWN)));

多谢提醒,应该是这样
        System.out.println(new BigDecimal("100").divide(new BigDecimal("12"),2, BigDecimal.ROUND_HALF_DOWN));
3 楼 jiangchao89911 2016-06-17  
使用误区四:除不尽,这样写似乎也不对啊
System.out.println(new BigDecimal("100").divide(new BigDecimal("12").setScale(2, BigDecimal.ROUND_HALF_DOWN)));
2 楼 welcomezhang 2016-06-15  
string2020 写道
System.out.println(new BigDecimal(0.03));
结果为啥是:
0.0299999999999999988897769753748434595763683319091796875 

涉及到精度丢失及bigdecimal的构造原理,不太好解释,建议debug看一下
1 楼 string2020 2016-06-15  
System.out.println(new BigDecimal(0.03));
结果为啥是:
0.0299999999999999988897769753748434595763683319091796875 

相关推荐

    BigDecimal使用

    BigDecimal 使用 BigDecimal 是 Java 中一个用于处理金融和商业应用的类,其主要功能是提供高精度的数字计算。下面是关于 BigDecimal 的使用方法和注意事项: 1. 导包:在使用 BigDecimal 之前,需要导入 java....

    BigInteger BigDecimal 使用

    `com`这个文件夹名可能表示该压缩包中包含的是一个Java项目的源代码目录,其中可能包含了使用`BigInteger`和`BigDecimal`的例子或库。在实际学习和使用时,可以查看这些源代码来理解这两个类的具体用法和应用场景。...

    bigdecimal

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

    bigdecimal转integer.docx

    如果 `BigDecimal` 包含小数,但你想保留小数位并将小数部分转化为整数,可以先使用 `setScale()` 方法调整小数位,然后再调用 `intValue()`。例如: ```java BigDecimal bigDecimal = new BigDecimal(1.25); ...

    javascript版BigDecimal类库

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

    BigDecimal类

    * 由于一般数值类型,例如 double,不能准确地代表 16 位有效数以上的数字,在使用 BigDecimal 时,应用 BigDecimal(String) 构造器创建对象才有意义。 * 不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学...

    BigDecimal.js.zip

    使用BigDecimal.js库时,首先需要在HTML文件中引入"BigDecimal-all-last.min.js"。这可以通过在`<head>`或`<body>`标签中添加`<script>`标签来完成: ```html <script src="path/to/BigDecimal-all-last.min.js"> `...

    BigDecimal工具类.docx

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

    BigDecimal向Double转换

    - **避免浮点数运算误差**:在处理涉及小数点的运算时,使用BigDecimal可以避免由浮点数运算带来的误差问题。 ## 二、BigDecimal到Double的转换 ### 2.1 使用doubleValue()方法 最简单的方式是通过BigDecimal类...

    BigDecimal的计算

    本文将基于提供的代码片段来详细解释如何使用 `BigDecimal` 进行计算,并深入探讨其应用场景。 #### 关键知识点 ##### 1. BigDecimal 类的概述 `BigDecimal` 是 Java 中的一个类,它能够提供对任意精度的十进制数...

    java BigDecimal操作

    这篇博文(尽管链接不可用)可能涉及了BigDecimal的基本操作和常见用法。 首先,BigDecimal的构造方式主要有两种:通过字符串或通过long/int构造。例如,`new BigDecimal("123.45")`和`new BigDecimal(12345)`。...

    JS的高精度计算(BigDecimal)

    使用例 <!-- function //+ alert(new BigDecimal("10").add(new BigDecimal("3E+10"))); //- alert(new BigDecimal("10").subtract(new BigDecimal("3E+10"))); //* alert(new BigDecimal("10").multiply(new ...

    Java中BigDecimal的加减乘除、比较大小与使用注意事项

    在Java编程中,当涉及到需要精确数值计算的场景时,我们通常会使用`BigDecimal`类。这是因为`float`和`double`类型虽然适用于科学计算和工程计算,但它们基于二进制浮点运算,不能保证完全精确的结果。而`BigDecimal...

    MyEditTextApplication输入框BigDecimal计算价格

    本项目“MyEditTextApplication”专注于使用BigDecimal进行输入框内的价格计算,确保计算结果的高度精确,尤其是在处理小数点后的多位数字时。 BigDecimal是Java提供的一个大数类,它可以用来进行精确的浮点数运算...

    java中BigDecimal的操作方法

    在进行商业计算时,由于浮点数(double和float)存在精度问题,不能保证准确的结果,因此通常推荐使用BigDecimal来确保计算的精确性。本文将深入探讨BigDecimal的基本操作、应用场景及注意事项。 首先,创建...

    BigDecimal 总结

    BigDecimal 使用方法小节:包含构造方法及和、差、商、积等运算方式

    Java Bigdecimal使用原理详解

    Java Bigdecimal使用原理详解 Java Bigdecimal是Java语言中用于精确计算的类,它可以完善float和double类无法进行精确计算的缺憾。BigDecimal类位于java.math类包下,提供了多种构造函数和方法来实现精确计算。 ...

    BigDecimal.txt

    BigDecimal类型使用

    BigDecimal-CPP-master.zip

    标题中的"BigDecimal-CPP-master.zip"表明这是一个与BigDecimal类实现相关的C++项目压缩包。BigDecimal是一种可以处理任意...通过学习和使用`BigDecimal`类,开发者可以避免浮点数精度问题,从而获得更准确的计算结果。

    js_bigdecimal_1_0_1.zip

    需要注意的是,由于JavaScript的动态类型特性,使用BigDecimal库时需要特别注意类型转换,避免因隐式转换导致的精度问题。同时,大数计算可能会比常规的JavaScript数值计算更消耗性能,因此在不需要高精度的情况下,...

Global site tag (gtag.js) - Google Analytics