Tuesday, October 14, 2008

(5)二进制浮点运算中的四舍五入错误

大多数硬件平台和程序语言都提供了浮点数运算,比如Ruby中的Float类。由于硬件的原因,大部分浮点运算都采用二进制浮点运算来提高精度,他可以精确的描述类似1/10,1/100,1/1024等的小数部分,但是不幸的是并不像我们想的那样1/10的结果是0.1。
Ruby的Float类的计算结果可以无限接近0.1但是这还是无法满足我们的要求,比如看看下面这个例子:


0.4 - 0.3 == 0.1 # 两边是不等的

是不是很奇怪,原因是因为0.4-0.3的结果取近似值后与0.1不同。这个问题不是只存在于Ruby中所有基于IEEE-754 浮点运算规范的语言比如C,Java,JavaScript都存在这样的问题。
一个解决的办法是使用10进制计算代替二进制计算,Ruby标准库中提供了BigDecimal 类可以很好的解决我们的问题,尽管BigDecimal 的性能比Float类要差,但是应付我们平常的计算已经足够了(只要你不是编写科学计算程序)。

No comments: