2010-11-08 62 views
6

可能重复:
PHP Math Precision((171.36/1.19)== 144)是否为假?

这里是PHP

一个示例代码
echo (171.36/1.19) 
//[PHP] result: 144 
//[JavaScript] result: 144.00000000000003 
//[Manual] result : 144 

$var1 = 144; 
$converted = 171.36/1.19 


//Variable 1 is less than Converted? 
echo (($var1 < $converted)?"Yes":"No") 
//result: Yes 

//Variable 1 is equal to Converted? 
echo (($var1 == $converted)?"Yes":"No") 
//result: No 

echo (($converted == 144)?"Yes":"No") //--> NO 
echo (("144.00" == 144)?"Yes":"No") //--> YES 

你能不能给我一个简单的解释/回答,并告诉我说,PHP不越野车。

+25

电离辐射会导致CPU产生不正确的结果。我在我的办公桌上放了一瓶碘酒,每次浮点平等测试都失败了。 – mikerobi 2010-11-08 15:05:03

+2

我以为你应该服用2.1粒?有什么差距? – webbiedave 2010-11-08 16:36:43

回答

16

这是固有地涉及一定数量的错误的浮点计算的结果。任意实数不能精确地以大多数语言(包括PHP)使用的浮点格式存储。您会在许多其他语言中看到类似的结果。

http://php.net/manual/en/language.types.float.php(阅读粉红大盒)

+1

+1可能是最好的答案,因为它甚至涉及到PHP手册。 – cgp 2010-11-08 15:09:05

+0

我同意; +1指向PHP手册,这解释了这个不幸的常见误解。 – Randolpho 2010-11-08 15:10:54

19

你已经看到结果足够接近144,这是将它转换为字符串时显示的值 - 但它是而不是刚好是144,这就是为什么你在倒数第二行得到“否” 。

这与人们一次又一次碰到的浮点数相同。

171.36和1.19都不能在二进制浮点类型中精确表示。所以PHP对它们使用非常接近的近似值。当您执行算术运算时,考虑到涉及原始数据的数据类型的限制(即“不完全”您所期望的),结果将尽可能精确。

底线:除非是非常特殊的情况,否则不要直接比较浮点值是否相等。通常最好在一定的容差内测试它们(例如,在144-0.00001和144 + 0.00001之间的值)。

+0

[新闻快讯:浮点数不是无限精确的。详细信息请参阅10:05000000004。](http://twitter.com/CrystalEmpGames/status/27160772411) – 2010-11-09 18:23:53

1

PHP不是越野车。它仅显示144,因为它在将浮点数转换为字符串以便打印时将其舍入为12位有效数字。

如果将数字打印为17位小数点,您将看到结果确实为144.00000000000003,与Javascript的结果相同。

(其他的答案也解释了为什么结果不完全是144不已,我不打算在此不再重复。)

示例代码见http://www.ideone.com/u0yB8

5

The Floating-Point Guide

为什么我的数字,像0.1 + 0.2加起来一个漂亮的圆0.3,而是我得到一个奇怪>导致像0.30000000000000004?

因为在内部,计算机使用的格式(二进制浮点)不能准确地表示 表示数字,如0.1,0.2或0.3。

当编译或解释代码时,您的“0.1”已经以该格式四舍五入到最接近的数字,甚至在计算发生之前会导致小的舍入误差。

基本上,当你写的文字171.36到您的代码和代码解释,计算机将使用数量是不是,事实上,171.36 - 所以一点也不奇怪,它会产生不同的结果当用于计算时。