当前位置:首页 > Java技术 > [转]double与BigDecimal

[转]double与BigDecimal

2022年09月15日 23:28:22Java技术16

转自:http://superivan.iteye.com/blog/963628

[1] 精确的浮点运算: 
在Java里面,有时候为了保证数值的准确性需要精确的数据,先提供一个例子就可以发现问题了: 

public class FloatNumberTester {
    public static void main(String args[]){
        System.out.println(0.05+0.01);
        System.out.println(1.0 - 0.42);
        System.out.println(4.015 * 100);
        System.out.println(123.3 / 100);
    }
}

 按照我们的期待,上边应该是什么结果呢,但是看输出我们就会发现问题了: 

0.060000000000000005
0.5800000000000001
401.49999999999994
1.2329999999999999

这样的话这个问题就相对严重了,如果我们使用123.3元交易,计算机却因为1.2329999999999999而拒绝了交易,岂不是和实际情况大相径庭。 

[2] 四舍五入: 
另外的一个计算问题,就是四舍五入。但是Java的计算本身是不能够支持四舍五入的,比如: 

public class GetThrowTester {
    public static void main(String args[]){
        System.out.println(4.015 * 100.0);
    }
}

这个输出为: 

401.49999999999994 
所以就会发现这种情况并不能保证四舍五入,如果要四舍五入,只有一种方法java.text.DecimalFormat:  

import java.text.DecimalFormat;
public class NumberFormatMain {
    public static void main(String args[]){
        System.out.println(new DecimalFormat("0.00").format(4.025));
        System.out.println(new DecimalFormat("0.00").format(4.024));
    }
}

上边代码输出为:  

4.02
4.02

发现问题了么?因为DecimalFormat使用的舍入模式, 舍入模式 详情参见本文最后部分。 
[3] 浮点输出: 
  Java浮点类型数值在大于9999999.0就自动转化成为科学计数法,看看下边的例子: 

 public class FloatCounter {
    public static void main(String args[]){
        System.out.println(9969999999.04);
        System.out.println(199999999.04);
        System.out.println(1000000011.01);
        System.out.println(9999999.04);
    }
}  
 输出结果为:    
9.96999999904E9 
1.9999999904E8 
1.00000001101E9 
9999999.04

但是有时候我们不需要科学计数法,而是转换成为字符串,所以这样可能会有点麻烦。 
总结: 
所以在项目当中,对于浮点类型以及大整数的运算 还是尽量不要用double,long等基本数据类型以及其包装类,还是用Java中提供的BigDecimal,BigInteger等大数值类型来代替吧。 
但这里特别说明一下BigDecimal类的两个构造函数的区别,他们分别是: 
new BigDecimal(String  val ) 和 new BigDecimal(double  val ) 
先看例子:  

public class BigDecimalMain {
    public static void main(String args[]){
        System.out.println(new BigDecimal(123456789.01).toString());
        System.out.println(new BigDecimal("123456789.01").toString());
    }
}

输出结果有一次令人意外了,同时两者之间的区别也一目了然了: 

123456789.01000000536441802978515625 
123456789.01

所以在 就是想利用double原始类型进行了相关计算之后再转成BigDecimal类型 的场合下,为了防止精度出现偏离,建议使用参数为String类型的该构造方法。即new BigDecimal(String  val )。 

补充:

  • BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,由于创建对象会引起开销,因此它们不适合于大量的数学运算,应尽量使用longfloatdouble等基本类型做科学计算或者工程计算。设计BigIntegerBigDecimal的目的是用来精确地表示大整数和小数,常用于商业计算中。
  • BigDecimal够造方法的参数类型有4种,其中的两个用BigInteger构造,另一个是用double构造,还有一个使用String构造。应该避免使用double构造BigDecimal,因为:有些数字用double根本无法精确表示,传给BigDecimal构造方法时就已经不精确了。比如,new BigDecimal(0.1)得到的值是0.1000000000000000055511151231257827021181583404541015625。使用new BigDecimal("0.1")得到的值是0.1。因此,如果需要精确计算,用String构造BigDecimal,避免用double构造,尽管它看起来更简单! 
  • equals()方法认为0.10.1是相等的,返回true,而认为0.100.1是不等的,结果返回false。方法compareTo()则认为0.10.1相等,0.100.1也相等。所以在从数值上比较两个BigDecimal值时,应该使用compareTo()而不是 equals()
  • 另外还有一些情形,任意精度的小数运算仍不能表示精确结果。例如,1除以9会产生无限循环的小数 .111111...。出于这个原因,在进行除法运算时,BigDecimal可以让您显式地控制舍入。

作者:myLittleGarden
来源链接:https://www.cnblogs.com/sunada2005/p/4665664.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/41509.html

标签: BigDecimal
分享给朋友:

“[转]double与BigDecimal” 的相关文章

[转]BigDecimal使用(整理)

原文地址:https://www.jianshu.com/p/2947868d76eb 应用场景 大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。比如:货币 使用 1、构建BigDecima...

【java提高】(19)---BigDecimal详解和精度问题

【java提高】(19)---BigDecimal详解和精度问题

BigDecimal详解和精度问题 一、背景 在实际开发中,对于 不需要任何准确计算精度的属性可以直接使用float或double,但是如果需要精确计算结果,则必须使用BigDecimal,例如价格、质量。 为什么这么说,主要有两点...

BigDecimal<转载>

前言 我们都知道浮点型变量在进行计算的时候会出现丢失精度的问题。如下一段代码: System.out.println(0.05 + 0.01); System.out.println(1.0 - 0.42); System.out.printl...

Java BigDecimal 的舍入模式(RoundingMode)详解

  BigDecimal 有 8 种 RoundingMode(舍入模式),分别总结如下。 一、RoundingMode 详解 ROUND_UP 进位制:不管保留数字后面是大是小 (0 除外) 都会进 1。结果会向原点的反方向对齐,正...

Java BigDecimal详解

原文地址:http://blog.csdn.net/jackiehff/article/details/8582449#comments 1.引言         借用《...

BigDecimal学习笔记

BigDecimal的运算 BigDecimal的运算——加减乘除 一、函数使用 1、尽量用字符串的形式初始化 BigDecimal num12 = new BigDecimal("0.005"); BigDecimal num22...

BigDecimal在使用中遇到的问题

BigDecimal在使用中遇到的问题

问题出处 今天在做活动统计的时候遇到的问题,数据库使用的字段为字符串来存储金额,解释就是不确定奖励是物品还是金钱,所以使用字符串来存储的,在查询做统计的时候需要对这个字段进行相加操作,本来想了下在mapper里直接使用sql来进行统计,后来测试是行...

Java中BigDecimal解决精度丢失问题

Java中BigDecimal解决精度丢失问题

  1.我们先看一个例子 可以看到在Java中进行浮点数运算的时候,会出现丢失精度的问题。那么我们如果在进行商品价格计算的时候,就会出现问题。很有可能造成我们手中有0.06元,却无法购买一个0.05元和一个0.01元的商品。因为如上所示,他们两个的总...

使用BigDecimal运算结果老是为0?老是没作用?来看看BigDecimal运算的正确姿势吧!

使用BigDecimal运算结果老是为0?老是没作用?来看看BigDecimal运算的正确姿势吧!

BigDecimal是开发中经常使用到的类,在涉及金额相关的字段时,精度要求是非常严格的,这也是不用double的原因了。没用过的开发者通常会遇到一个问题,就是**经过一通计算,没有得到预期的结果,得到的还是原来未参与运算的那个值。**通常大家看到最多的...

java BigDecimal的操作

java BigDecimal的操作 今天给大家讲一下java中BigDecimal的操作。由于double,float的精度不够,因此在进行商业计算的时候要使用的BigDecimal。BigDecimal对象创建如下: BigDecimal b =...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。