Java中需要精确计算的,不要用float, double, 请用BigDecimal

float,double都有误差,适合做科学计算或工程计算,像商业应用,特别是购物,计费等系统,就一定要用这个BigDecimal,精确。 

比如我们定义一个double是0.01,可能将来打印出来或计算的时候,实际上是0.010000000003456这样的数值,那么,如果我们用这样的数值去计算的话,随着计算的增多和double数的增多,误差就会越来越大,这在商业计算中是不允许的。比如,有可能10块钱在我们程序中就是9.999999999999348,这样,这个人就买不了10块钱的东西了。 

而且,float、double这些东西有时还会变成科学技术法的表示方法,也挺烦人的。比如,在我们的EasyCluster中,计算任务运行完成后,后台将任务消费数据报了上来,这些数据都是string格式的,然后EC把这些数值转换成了float,然后计算,最后将计算出来的数值存入了数据库。但是这样就有问题,首先就是上面提到的误差问题了,这不说了,其次就是有的任务是错任务,运行了一下就立刻消失了,所以这种任务的消费数据就非常小,比如CPU运行时就是0.000001秒,那么,这个数据在变成float之后,EC做了一个取短的动作(因为小数位数太长,EC只保留了小数点后面四位的东西,而Java有没有提供这样现成的四舍五入的函数,于是我就自己写了一个truncString的函数,这个函数接受一个String,然后截断到小数点后四位),那么,在这个取短中就出现问题了,因为0.000001变成float之后其实是1.00000E-6,这个float变成String后也是1.00000E-6,这样一阶段,这个float数字就立刻变成1了,扩大了1000000倍!! 

总而言之,使用float或double做精确计算有很大问题,我们需要用BigDecimal。具体请看附件中的文章,非常的不错。有例子有代码。 

最关键的一点就是使用new BigDecimal(String input)这个构造函数,因为这个构造函数出来的数值是精确的,也就是说,传入"0.1"出来的数值就是0.1,不会是0.10000000456这样的东西。所以,文章中由此引申出了,在数据库中,也应该以字符串的方式来存储数据,这样数据从数据库中取出,直接用BigDecimal变成精确的数值,然后做加减乘除、取整、取余、四舍五入都是精确的。

转载于:https://www.cnblogs.com/super119/archive/2011/01/03/1924530.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值