Floating Point Precision and Accuracy

Jun 12th, 2007 | Filed under PHP

其实这不是 PHP 的问题,其它编程语言中都会有类似的问题。

首先看看 PHP 手册上面怎么说的:

Floating point precision

It is quite usual that simple decimal fractions like 0.1 or 0.7 cannot be converted into their internal binary counterparts without a little loss of precision. This can lead to confusing results: for example, floor((0.1+0.7)*10) will usually return 7 instead of the expected 8 as the result of the internal representation really being something like 7.9999999999….

This is related to the fact that it is impossible to exactly express some fractions in decimal notation with a finite number of digits. For instance, 1/3 in decimal form becomes 0.3333333. . ..

So never trust floating number results to the last digit and never compare floating point numbers for equality. If you really need higher precision, you should use the arbitrary precision math functions or gmp functions instead.

简单的说,float 存在精度问题,是不可依赖的,比如 0.1 + 0.7,一年级的小朋友都知道答案是 0.8,但是实际上计算机计算的值为 0.7999999……

所以永远不要拿 float 来做大小比较,比如下面的代码:

$sum = 0.1 + 0.7;
if ($sum == 0.8) {
    /** some code **/
}

上面 if 块中的代码永远不会执行,因为 $sum != 0.8,简单的方法就是把 $sum 转换为 string 类型,PHP 会自动调整精度。

$sum = 0.1 + 0.7;
if ((string) $sum === '0.8') {
    /** some code **/
}

这样就没有问题了:)

Tags:
Comments are closed.