奇怪的ceil()函数工作(php)

时间:2015-10-23 06:30:29

标签: php ceil

此代码:

echo (40 * (10 / 100 + 1)); //44
echo (50 * (10 / 100 + 1)); //55
echo ceil(40 * ((10 / 100) + 1)); //44
echo ceil(50 * ((10 / 100) + 1)); //56 (!)

我认为,由于浮点(55.0000000001 => 56),“56”,但我不明白为什么“40”结果是“44”,而不是“45”

2 个答案:

答案 0 :(得分:5)

55实际上不是55.您可以轻松验证:

<?php
$x = (40 * (10 / 100 + 1)); // 44
$y = (50 * (10 / 100 + 1)); // 55
echo '$x == 44: ' . ($x == 44 ? 'True' : 'False') . "\n";
echo '$y == 55: ' . ($y == 55 ? 'True' : 'False') . "\n";
echo '$y > 55: ' . ($y > 55 ? 'True' : 'False') . "\n";
echo $y - 55;

收率:

$x == 44: True
$y == 55: False
$y > 55: True
7.105427357601E-15

正如你所看到的那样差异很小(7.1 * 10 ^ -15),但仍然大于55,所以ceil会将其四舍五入。

您看到55的原因是因为回显它会转换浮动into a string

  

字符串转换是在需要字符串的表达式范围内自动完成的。使用echo或print函数时,或者将变量与字符串进行比较时会发生这种情况。

对于此转换,标准截断行为将在某个时刻切断数字。这由precision configuration parameter配置,默认为14.您可以通过使用sprintf自定义精度来避免此行为:

echo sprintf('%.50f', $y);
// 55.00000000000000710542735760100185871124267578125000

答案 1 :(得分:1)

我们需要注意浮点精度 http://php.net/manual/en/language.types.float.php

  

可以完全表示为浮点的有理数   基数10中的数字,如0.1或0.7,没有确切的数字   表示为使用的基数2中的浮点数   在内部,无论尾数的大小。因此,他们不可能   转换成内部二进制对应物而没有少量损失   精度这可能会导致令人困惑的结果:例如,   floor((0.1 + 0.7)* 10)通常会返回7而不是预期的8,   因为内部表示将是类似的   7.9999999999999991118 ....

这就是问题的答案为什么我的数字不加起来? http://floating-point-gui.de/。简明扼要地解释为什么会得到意想不到的结果