编程语言数据失真原因概述

在java语言中,对于要求精确的计算,都推荐使用诸如BigDecimal这样的工具类来处理,而不是用float或double来直接计算,这是因为单精度浮点数和双精度浮点数在计算过程中可能会出现误差,这在商业或军事项目是要绝对避免的!

今天我们不讨论为什么BigDecimal可以实现精确计算,我们讲一下,为什么会出现误差。

先说结论:不是所有十进制数都有相等的二进制形式(整数没有问题,问题出现在小数部份)

我们在写程序时,使用的通常都是十进制数,譬如,float price=2.2f;好,这个数字正常人都懂,但是机智的计算机却完全不明白,因为它只能识别1,0这两个数字。当要把2.2f转换成double时,误差就出现了,这又是为什么呢?2.2f在计算机中会以单精度小数的格式保存下来,那么问题来了,计算机能将2.2等值的转换成二进制形式吗?答案是:no!计算机只能保存一个与2.2非常接近的一个数。

2.2的二进制形式:10.00110011001100110011001100110011001100110011........一个无限循环的形式。计算机的存储空间是有限的,按单精度浮点数,只能存储24位尾数位,于是在计算机中保存的样子就是:

符号位   指数位             尾数

 0          0000 0001       00011001100110011001100

为了方便统一使用原码。

而10.0011001100110011001100对应的十进制数是个啥有兴趣的自己算,反正不是2.2。那么由它转换成double类型,自然也不能得到准确的2.2的值了。

所以说数据误差的问题,与进制转换、数据存储都是有密切关系的。


参考:关于浮点数的精度与取值范围的问题

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值