我一直在与PHP的ceil()函数搏斗,给我一些错误的结果 - 考虑以下几点:
$num = 2.7*3; //float(8.1)
$num*=10; //float(81)
$num = ceil($num); //82, but shouldn't this be 81??
$num/=10; //float(8.2)
我有一个可能有任意小数位数的数字,我需要将它四舍五入到小数点后一位。 即8.1应为8.1,8.154应为8.2,而8应为8。
我如何到达那里是取数字,乘以10,ceil()它,然后除以10但是你可以看到我在某些情况下增加了额外的.1。
任何人都可以告诉我为什么会这样,以及如何解决它?
任何帮助非常感谢
编辑:有+ = 10而不是* = 10:S
编辑2: 我没有明确提到这一点,但我需要小数总是向上舍入,永远不会下降 - 这个答案到目前为止最接近:
rtrim(rtrim(sprintf('%.1f', $num), '0'), '.');
然而当我需要3.9时,将3.84下降到3.8。 对不起,这个问题并不清楚:(
最终编辑:
我最终做的是:
$num = 2.7*3; //float(8.1)
$num*=10; //float(81)
$num = ceil(round($num, 2)); //81 :)
$num/=10; //float(8.1)
哪个有效:)
答案 0 :(得分:2)
这很可能是由于浮点错误造成的。
您可能有幸尝试此过程。
<?php
$num = 2.7*3;
echo rtrim(rtrim(sprintf('%.1f', $num), '0'), '.');
答案 1 :(得分:2)
花车可能是一件善变的事情。并非所有实数都可以用有限数量的二进制位正确表示 事实证明,0.7的小数部分是这些数字中的一个(在0.10之后出现无穷大重复“1100”)。你得到的数字远远超过0.7,所以当你乘以10时,你的数字会略高于7。
您可以做的是进行健全检查。带你浮点数并减去它的整数形式。如果结果值小于,例如0.0001,则将其视为内部舍入错误并保持原样。如果结果大于0.0001,则通常应用ceil()。
编辑:如果您在Windows上显示这是打开内置计算器应用程序的一个有趣示例。放入“4”然后应用平方根函数(x ^ y,其中y = 0.5)。你会看到它正确显示“2”。现在,从中减去2,你会发现结果没有0。这是由于内部舍入错误在尝试计算4的平方根时引起的。当先显示数字2时,它知道那些非常遥远的尾随数字可能是舍入错误,但是当这些都是剩下的时候,它会得到一个有点困惑。
(在任何人谈到我之前,我明白这是过于简单的,但我认为这是一个不错的例子。)
答案 2 :(得分:0)
问题在于浮点数与你期望的一样。你的2.7 * 3可能会出现像81.0000000000000000001,其中ceil()高达82.对于这种事情,你必须用一些精确的检查包裹你的ceil / round / floor来处理那些额外的微观差异。
答案 3 :(得分:0)
使用%f
代替%.1f
。
echo rtrim(rtrim(sprintf('%f', $num), '0'), '.');
答案 4 :(得分:0)
为什么不试试这个:
$num = 2.7*3;
$num *= 100;
$num = floor($num);
$num /= 10;
$num = ceil($num);
$num /= 10;
答案 5 :(得分:0)
将您的号码转换为字符串并取消该字符串。
function roundUp($number, $decimalPlaces){
$multi = pow(10, $decimalPlaces);
$nrAsStr = ($number * $multi) . "";
return ceil($nrAsStr) / $multi;
}