如果输入是不带小数的浮点,PHP ceil将给出错误的结果 我一直在用PHP的CELL()函数摔跤,让我有点错误的结果-考虑以下内容: $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)

如果输入是不带小数的浮点,PHP ceil将给出错误的结果 我一直在用PHP的CELL()函数摔跤,让我有点错误的结果-考虑以下内容: $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),php,floating-point,ceil,Php,Floating Point,Ceil,我有一个数字,可以有任何小数位数,我需要它四舍五入到小数点后一位。 i、 e 8.1应为8.1,8.154应为8.2,8应保留为8 我是如何得到这个数字的,乘以10,然后除以10,但是你可以看到,在某些情况下,我得到了一个额外的.1 有人能告诉我为什么会发生这种情况,以及如何解决它吗 非常感谢您的帮助 编辑:had+=10而不是*=10:S 编辑2: 我没有明确提到这一点,但我需要小数点总是向上舍入,而不是向下舍入-这是迄今为止最接近的答案: rtrim(rtrim(sprintf('%.1f'

我有一个数字,可以有任何小数位数,我需要它四舍五入到小数点后一位。 i、 e 8.1应为8.1,8.154应为8.2,8应保留为8

我是如何得到这个数字的,乘以10,然后除以10,但是你可以看到,在某些情况下,我得到了一个额外的.1

有人能告诉我为什么会发生这种情况,以及如何解决它吗

非常感谢您的帮助

编辑:had+=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)

这是有效的:)

问题是浮点数很少是你所期望的。您的2.7*3可能是81.0000000000000000001,ceil()的上限是82。对于这种情况,您必须使用一些精度检查来包装ceil/round/floor调用,以处理这些额外的微观差异。

这很可能是由于浮点错误造成的

您可能会幸运地尝试此过程

<?php
$num = 2.7*3;
echo rtrim(rtrim(sprintf('%.1f', $num), '0'), '.');

浮动可能是一件易变的事情。并非所有实数都可以用有限个二进制位正确表示。
事实证明,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之前,它知道这些非常遥远的尾随数字可能是一个舍入错误,但当这些都是剩下的,它会有点困惑


(在任何人对我了解之前,我理解这是过于简单化了,但是我认为这是一个很好的例子。)

< p>使用<代码> %f>代码>而不是<代码> %1f < /代码>。
echo rtrim(rtrim(sprintf('%f', $num), '0'), '.');
为什么不试试这个:

$num = 2.7*3; 
$num *= 100; 
$num = floor($num); 
$num /= 10; 
$num = ceil($num); 
$num /= 10;

将您的数字转换为字符串并输入字符串

function roundUp($number, $decimalPlaces){
    $multi = pow(10, $decimalPlaces);
    $nrAsStr = ($number * $multi) . "";
    return ceil($nrAsStr) / $multi;
}

这给了2个小数位,我需要1-这段代码可以工作:echo rtrim(rtrim(sprintf('.1f',$num),'0'),');否则,答案很好,谢谢