由BigDecimal引发的思考

本文探讨了Java中float和double类型的运算不准确性,并通过示例介绍了如何利用BigDecimal类进行精确计算,包括构造方法的选择及常见操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文综合网上牛人以及Java API所写,还有自己的一些项目经历。主要实用工具Eclipse3.5、jdk1.6,测试框架JUnit4等。

floatdouble只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal

                                                                                                                                       -----《Effective Java

看一个小例子:

 

测试结果:

 

让人不可思议,怎么会与自己的想象差的那么远!但,现实确实如此!

Java中的简单浮点数类型floatdouble不能够进行运算。不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,但是多试几次(可以做一个循环)就可以试出类似上面的错误。

再者,Math类、DecimalFormat类有对应的处理数据的方法。实例代码:

 

显示结果:

 

哎,还是让人很失望。

难道在工程中,我们就这样计算吗?当然不是,Java还没有“挫”,呵呵!下面谈谈BigDecimal。

BigDecimal有很多构造方法,详看api文档。这里主要说说下面两个构造方法:

 

关于其他的构造方法,这里不赘述,举一反三吧!

这两个构造方法,建议采用第二个,具体原因在api上解释的很清楚。

 

翻译一下:

 

使用BigDecimal,可以获得交准确的计算结果,并且可以自己定义小数精度,具有一定的灵活性。实例代码:

 

其中,BigDecimal有很多常量字段。ROUND_HALF_UP表示四舍五入。实例代码:

 

在JUnit4的帮助下,很好地完成了许多测试,解开了很多疑惑。如果你不明白最好还是多加测试。也许,你有更多的发现。

在好奇心的驱使下,又看看BigDecimal源码,主要涉及到其valueOf(double val)方法,该方法是静态方法,源码如下:

 

可以看出,valueOf(double val)方法以BigDecimal(Double.toString(val))方式返回一个BigDecimal对象。所以在以double为源的时候创

建BigDecimal对象,可以采用该方法。修改上面实例代码如下:

 

在看源代码的时候,经常看到别人使用valueof**方法,难道它有什么与众不同吗?研究一下ing.....

首先,研究一下Integer的创建方式:

 

根据注释来看,equals比较之后都是true,这很好理解。因为Integer重写了equals方法,只要内容相同,equals比较就是true。再者new方式产出的对象用”=“比较肯定是false,但是为什么同样是valueOf,一个是true,而另一个却是false???!!!

不要急,看看Integer源码:

 

IntegerCache是静态内部类。从源码可以看出使用valueOf方法创建Integer实例时:

当这个值在-128和127之间时,会用缓存保存起来,供多次使用,以节约内存。 
如果不在这个范围内,则创建一个新的Integer对象。 再看一个实例:

 

晕。。居然false,why????

反编译一下这段代码,看看它神秘的面纱。

 

哦,原来如此。自动装箱使用的就是valueOf方法,额的神啊!那么自动拆箱是什么原理?

 

另外,算是提示吧?!

初始化一个字符串,  String s1 = "s1"; 这样的代码肯定比  String s2 = new String("s2");代码强,将其他类型的值转换成String的时候,valueof方法比new方法效率也高。 

文章到此为止,希望对你有用!


非常感谢:

http://www.cnblogs.com/sharewind/archive/2007/09/08/886749.html 提供大量关于BigDecimal的例子代码

http://honda418.iteye.com/blog/315893 探讨了Integer的陷阱 

http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 为自动装箱与拆箱提供精彩的代码

 

这篇文章引用了他们的某些代码片段,如果不是他们的无私奉献,估计我没有勇气和能力写出这篇文章,再次感谢他们,向他们学习!!! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值