关于分裂结果的Floor()

时间:2014-08-06 09:33:47

标签: php

根据计算:(14056567 /(14056567/100)),这等于浮点数100。 在浮点数100上使用PHP floor()应始终返回100。

但这是我的问题:当输入浮点数100是除法的结果时,floor()返回99.

测试1:

<?php
$test = (14056567/(14056567/100));
var_dump($test);
$test = floor($test);
var_dump($test);

// output:
// float(100)
// float(99)

测试2:

<?php
$test = (14056567/(14056567/100));
$test = (double)$test;
$test = (float)$test;
$test = floatval($test);
$test = 0 + $test;
var_dump($test);
$test = floor($test);
var_dump($test);

// output:
// float(100)
// float(99)

测试3:

<?php
$test = (14056567/(14056567/100));
$test = floatval('' . $test);
var_dump($test);
$test = floor($test);
var_dump($test);

// output:
// float(100)
// float(100)

所以只有当连接一个字符串和我的浮点数时,它才会在一个floor()之后给出我期望的结果。

根据以下链接中的回复:https://bugs.php.net/bug.php?id=6851 原因是100等于99.999999的浮点数,即使这是真的,为什么在不是除法的结果时不是这种情况呢?

2 个答案:

答案 0 :(得分:3)

 14056567/100 = 140565.67

对人类来说很好,因为我们使用十进制,计算机使用二进制,而.67并不能很容易地用二进制表示(我甚至不能100%确定它是否可以完全代表那个数字,即使是完美的精确度。)

如果您为其生成十六进制,结果类似于0.ab851eb851eb88,但0.ab851eb851eb88实际上是0.670,000,000,02附近的数字。

按此近似值进行除法时,得到的数字最好表示为100,但实际上更像是99.999,999,999,98,当您调用var_dump时会显示该数字关闭。

当你打电话给它时,它会给你99个,因为floor(99.9999999)实际应该生成什么,100的答案是四舍五入的结果,楼层的结果对于你的数字是正确的#39 ;重新使用。

答案 1 :(得分:2)

尝试使用以下脚本查看最新情况:

<?php

printf ("# No precision lost\n");
printf ("14056567.0 = %.53f\n\n", 14056567.0);

printf ("# No precision lost\n");
printf ("100.0 = %.53f\n\n", 100.0);

printf ("# Precision lost, because 140565.67 can't be represented precisely in float\n");
printf ("14056567.0/100.0 = %.53f\n\n", 14056567.0 / 100.0);

printf ("# Same here without division\n");
printf ("140565.67 = %.53f\n\n", 140565.67);

printf ("# Lost precision carrying on...\n");
printf ("14056567.0/140565.67 = %.53f\n\n", 14056567.0 / 140565.67);

printf ("# This is OK\n");
printf ("14056567.0*100.0/14056567.0 = %.53f\n\n", 14056567.0 * 100.0 / 14056567.0);

// Output:
// # No precision lost
// 14056567.0 = 14056567.00000000000000000000000000000000000000000000000000000
// 
// # No precision lost
// 100.0 = 100.00000000000000000000000000000000000000000000000000000
// 
// # Precision lost, because 140565.67 can't be represented precisely in float
// 14056567.0/100.0 = 140565.67000000001280568540096282958984375000000000000000000
// 
// # Same here without division
// 140565.67 = 140565.67000000001280568540096282958984375000000000000000000
// 
// # Lost precision carrying on...
// 14056567.0/140565.67 = 99.99999999999998578914528479799628257751464843750000000
// 
// # This is OK
// 14056567.0*100.0/14056567.0 = 100.00000000000000000000000000000000000000000000000000000

?>