简体   繁体   English

PHP 中四舍五入到最接近的五的倍数

[英]Round up to nearest multiple of five in PHP

I want a php function which returns 55 when calling it with 52.我想要一个 php 函数,当用 52 调用它时返回 55。

I've tried the round() function:我试过round()函数:

echo round(94, -1); // 90

It returns 90 but I want 95 .它返回90但我想要95

Thanks.谢谢。

This can be accomplished in a number of ways, depending on your preferred rounding convention:这可以通过多种方式完成,具体取决于您首选的舍入约定:

1. Round to the next multiple of 5, exclude the current number 1.四舍五入到下一个5的倍数,排除当前数

Behaviour: 50 outputs 55, 52 outputs 55行为: 50 输出 55​​, 52 输出 55

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

2. Round to the nearest multiple of 5, include the current number 2.四舍五入到最接近的5的倍数,包括当前数字

Behaviour: 50 outputs 50, 52 outputs 55, 50.25 outputs 50行为:50 输出 50、52 输出 55​​、50.25 输出 50

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

3. Round up to an integer, then to the nearest multiple of 5 3.四舍五入到一个整数,然后到最接近的5的倍数

Behaviour: 50 outputs 50, 52 outputs 55, 50.25 outputs 55行为:50 输出 50、52 输出 55​​、50.25 输出 55

function roundUpToAny($n,$x=5) {
    return (ceil($n)%$x === 0) ? ceil($n) : round(($n+$x/2)/$x)*$x;
}
  1. Divide by 5除以 5
  2. round() (or ceil() if you want to round up always ) round() (或ceil()如果您想始终向上舍入
  3. Multiply by 5.乘以 5。

The value 5 (the resolution / granularity) can be anything — replaced it in both step 1 and 3值 5(分辨率/粒度)可以是任何值 — 在步骤 1 和 3 中替换它

So in summary:所以总结一下:

    $rounded_number = ceil( $initial_number / 5 ) * 5

Round down:向下舍入:

$x = floor($x/5) * 5;

Round up:围捕:

$x = ceil($x/5) * 5;

Round to closest (up or down):四舍五入到最接近(向上或向下):

$x = round($x/5) * 5;
   echo $value - ($value % 5);

我知道这是一个老问题,但恕我直言,使用模数运算符是最好的方法,而且比公认的答案要优雅得多。

Try this little function I wrote.试试我写的这个小函数。

function ceilFive($number) {
    $div = floor($number / 5);
    $mod = $number % 5;

    If ($mod > 0) $add = 5;
    Else $add = 0;

    return $div * 5 + $add;
}

echo ceilFive(52);

From Gears library来自Gears

MathType::roundStep(50, 5); // 50
MathType::roundStep(52, 5); // 50
MathType::roundStep(53, 5); // 55

MathType::floorStep(50, 5); // 50
MathType::floorStep(52, 5); // 50
MathType::floorStep(53, 5); // 50

MathType::ceilStep(50, 5); // 50
MathType::ceilStep(52, 5); // 55
MathType::ceilStep(53, 5); // 55

Source:来源:

public static function roundStep($value, int $step = 1)
{
    return round($value / $step) * $step;
}

public static function floorStep($value, int $step = 1)
{
    return floor($value / $step) * $step;
}

public static function ceilStep($value, int $step = 1)
{
    return ceil($value / $step) * $step;
}

Here is my version of Musthafa's function.这是我对Musthafa函数的版本。 This one is more complex but it has support for Float numbers as well as Integers.这个更复杂,但它支持浮点数和整数。 The number to be rounded can also be in a string.要舍入的数字也可以在字符串中。

/**
 * @desc This function will round up a number to the nearest rounding number specified.
 * @param $n (Integer || Float) Required -> The original number. Ex. $n = 5.7;
 * @param $x (Integer) Optional -> The nearest number to round up to. The default value is 5. Ex. $x = 3;
 * @return (Integer) The original number rounded up to the nearest rounding number.
 */
function rounduptoany ($n, $x = 5) {

  //If the original number is an integer and is a multiple of 
  //the "nearest rounding number", return it without change.
  if ((intval($n) == $n) && (!is_float(intval($n) / $x))) {

    return intval($n);
  }
  //If the original number is a float or if this integer is 
  //not a multiple of the "nearest rounding number", do the 
  //rounding up.
  else {

    return round(($n + $x / 2) / $x) * $x;
  }
}

I tried the functions from Knight , Musthafa and even the suggestion from Praesagus .我尝试了KnightMusthafa甚至Praesagus的建议的功能 They don't have support for Float numbers and the solutions from Musthafa's & Praesagus do not work correctly in some numbers.他们不支持浮点数,并且Musthafa's & Praesagus的解决方案在某些数字中无法正常工作。 Try the following test numbers and do the comparison yourself:尝试以下测试数字并自己进行比较:

$x= 5;

$n= 200;       // D = 200     K = 200     M = 200     P = 205
$n= 205;       // D = 205     K = 205     M = 205     P = 210
$n= 200.50;    // D = 205     K = 200     M = 200.5   P = 205.5
$n= '210.50';  // D = 215     K = 210     M = 210.5   P = 215.5
$n= 201;       // D = 205     K = 205     M = 200     P = 205
$n= 202;       // D = 205     K = 205     M = 200     P = 205
$n= 203;       // D = 205     K = 205     M = 205     P = 205

** D = DrupalFever K = Knight M = Musthafa P = Praesagus

乘以 2,四舍五入到 -1,再除以 2。

I do it like this:我这样做:

private function roundUpToAny(int $n, $x = 9)
{
    return (floor($n / 10) * 10) + $x;
}

Tests:测试:

assert($this->roundUpToAny(0, 9) == 9);
assert($this->roundUpToAny(1, 9) == 9);
assert($this->roundUpToAny(2, 9) == 9);
assert($this->roundUpToAny(3, 9) == 9);
assert($this->roundUpToAny(4, 9) == 9);
assert($this->roundUpToAny(5, 9) == 9);
assert($this->roundUpToAny(6, 9) == 9);
assert($this->roundUpToAny(7, 9) == 9);
assert($this->roundUpToAny(8, 9) == 9);
assert($this->roundUpToAny(9, 9) == 9);
assert($this->roundUpToAny(10, 9) == 19);
assert($this->roundUpToAny(11, 9) == 19);
assert($this->roundUpToAny(12, 9) == 19);
assert($this->roundUpToAny(13, 9) == 19);
assert($this->roundUpToAny(14, 9) == 19);
assert($this->roundUpToAny(15, 9) == 19);
assert($this->roundUpToAny(16, 9) == 19);
assert($this->roundUpToAny(17, 9) == 19);
assert($this->roundUpToAny(18, 9) == 19);
assert($this->roundUpToAny(19, 9) == 19);
function round_up($n, $x = 5) {
  $rem = $n % $x;
  if ($rem < 3)
     return $n - $rem;
  else
     return $n - $rem + $x;
}

I just wrote this function in 20 min, based on many results I found here and there, I don't know why it works or how it works!!我只是在 20 分钟内编写了这个函数,基于我在这里和那里找到的许多结果,我不知道它为什么起作用或如何起作用!! :D :D

I was mainly interested in converting currency numbers from this 151431.1 LBP to 150000.0 LBP.我主要对将货币数字从 151431.1 LBP 转换为 150000.0 LBP 感兴趣。 (151431.1 LBP == ~100 USD) which works perfectly so far, however I tried to make it somehow compatible with other currencies and numbers, but not sure if it works fine!! (151431.1 LBP == ~100 USD)到目前为止效果很好,但是我试图让它以某种方式与其他货币和数字兼容,但不确定它是否工作正常!!

/**
 * Example:
 * Input = 151431.1 >> return = 150000.0
 * Input = 17204.13 >> return = 17000.0
 * Input = 2358.533 >> return = 2350.0
 * Input = 129.2421 >> return = 125.0
 * Input = 12.16434 >> return = 10.0
 *
 * @param     $value
 * @param int $modBase
 *
 * @return  float
 */
private function currenciesBeautifier($value, int $modBase = 5)
{
    // round the value to the nearest
    $roundedValue = round($value);

    // count the number of digits before the dot
    $count = strlen((int)str_replace('.', '', $roundedValue));

    // remove 3 to get how many zeros to add the mod base
    $numberOfZeros = $count - 3;

    // add the zeros to the mod base
    $mod = str_pad($modBase, $numberOfZeros + 1, '0', STR_PAD_RIGHT);

    // do the magic
    return $roundedValue - ($roundedValue % $mod);
}

Feel free to modify it and fix it if there's anything wrong如果有任何问题,请随意修改并修复它

Probably you can also consider this one liner.可能你也可以考虑这一个班轮。 It's faster!它更快! Works for $num >= 0 and $factor > 0 .适用于$num >= 0$factor > 0

$num = 52;
$factor = 55;
$roundedNum = $num + $factor - 1 - ($num + $factor - 1) % $factor;

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

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