简体   繁体   English

php舍入值,尾随2位小数,5位的倍数

[英]php round off value with trailing 2 decimals and multiples of 5

I tried this function 我试过这个功能

function roundUpToAny($n,$x=5) {
    return (round($n)%$x === 0) ? round($n) : round(($n+$x/2)/$x)*$x;
}

echo roundUpToAny(4.52); // This show 5 instead of 4.55 //这个节目5而不是4.55

echo roundUpToAny(5.1); // This show 5 instead of 5.10 //这个节目5而不是5.10

How can i created such function 我怎样才能创造出这样的功能

I think the following function does what you want: 我认为以下功能可以满足您的需求:

function roundUpToAny($n, $x=5, $sf=2) {
  $scale = pow(10,$sf);
  return number_format(round(ceil($n*$scale / $x), $sf) * $x / $scale, $sf);
}

The first argument is the number to be converted, the second is the "rounding factor" (multiples of $x - you asked for 5 in the title of the question), the third is the number of figures after the decimal point. 第一个参数是要转换的数字,第二个参数是“舍入因子”( $x倍数 - 你在问题的标题中要求5 ),第三个是小数点后的数字。

Test: 测试:

echo roundUpToAny(1.23, 5, 2) ."\n";
echo roundUpToAny(4.54, 5, 2) ."\n";
echo roundUpToAny(5.101, 5, 3) ."\n";
echo roundUpToAny(1.19, 5, 3) ."\n";

Result: 结果:

1.25
4.55
5.105
1.190

UPDATE UPDATE

You pointed out in a follow-up that the above code fails for inputs of 1.1 and 2.2 . 您在后续文件中指出,上述代码对于1.12.2输入失败。 The reason for this is the fact that these numbers are not exactly representable in double precision (strange though this may sound) . 这样做的原因是这些数字在双精度上并不完全可以表示(虽然这可能听起来很奇怪) The following code compensates for this, by creating an intermediate value that is rounded to be an integer (and therefore can be represented exactly): 以下代码通过创建一个舍入为整数的中间值(因此可以精确表示)来对此进行补偿:

function roundUpToAny($n, $x=5, $sf=2) {
  $scale = pow(10,$sf);
  $temp = round($n * $scale, $sf); // get rid of small rounding errors
  return number_format(round(ceil($temp / $x), $sf) * $x / $scale, $sf);
}

Testing: 测试:

echo roundUpToAny(1.1, 5, 2) ."\n";

Result: 结果:

1.10

As expected. 正如所料。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM