开发者

Rounding Mechanism to nearest 0.05

开发者 https://www.devze.com 2022-12-08 18:35 出处:网络
I would like to solve rounding mechanism by using php4,5.2 and below (not 5.3) Currently I am doing 0.05 rounding, something like this page:

I would like to solve rounding mechanism by using php4,5.2 and below (not 5.3) Currently I am doing 0.05 rounding, something like this page:

http://www.bnm.gov.开发者_StackOverflowmy/index.php?ch=209&pg=657&ac=568

before rounding | after rounding

          89.90 | 89.90

          89.91 | 89.90

          89.92 | 89.90

          89.93 | 89.95

          89.94 | 89.95

          89.95 | 89.95

          89.96 | 89.95

          89.97 | 89.95

          89.98 | 90.00

          89.99 | 90.00

I try to use string to split it out and manually do adding, but not really a good solution, hoping here can find someone to solve it.


use this function

function rndfunc($x){
  return round($x * 2, 1) / 2;
}


Conceptually, the procedure can be done as:

  1. Divide by 0.05
    • or multiply by (1 / 0.05)
  2. Round to nearest integer
  3. Multiply by 0.05


You basically want to map values to a grid. The grid is defined as a multiple of .05. In general, you need to find the multiplicands your value lies between.

What isn't in the table are the negative numbers. You need to decide on whether to round away from zero (symmetrical) or always in the same direction (i.e. positive).

code:

$step = .05;
$multiplicand = floor( $value / $step );
$rest = $value % $step ;
if( $rest > $step/2 ) $multiplicand++; // round up if needed
$roundedvalue = $step*$multiplicand;


Multiply by two, then round, then divide by two.


Hint:-

$input1 = 24.05;

$things = abs($input * 20 ); // 481 ".05"s

$tenpcnt = abs($things / 10); // 48 ".05"s

$ouput = $tenpcnt / 20;

echo $ouput; // 2.40


function round5Sen ($value) { 

    return number_format(round($value*20,0)/20,2,'.','');
} 

echo round5Sen(155.13);
echo "\n";
echo round5Sen(155.12);
echo "\n";
echo round5Sen(155.0);
echo "\n";
echo round5Sen(155.18);
echo "\n";


I'm sure there are more elegant solutions, but this appears to suit the task:

<?php

// setup test
$start_num = 89.90;
$iterations = 10;

// loop through test numbers
for ($i = 0; $i < $iterations; $i++) {
  nickleRound($start_num + (0.01 * $i));
  echo "\n\n";
}

//
function nickleRound($num) {
  $p = 0.05;
  echo "\n" . 'p= ' . $p;

  $num = round($num, 2);
  echo "\n" . 'num= ' . $num;

  $r = ($num / $p);
  echo "\n" . 'r= ' . $r;

  $r2 = ceil($r) - $r;  
  echo "\n" . 'r2= ' . $r2;

  $a = round($num, 1);
  if (($r2 > 0) && ($r2 < 0.5)) {
    $a = $a + 0.05; 
  }
  echo "\n" . 'a= ' . $a;
}


Expanding a little on @xtofl to allow for more precise steps (not technically required for this question)

    $step         = 0.0005;
    $multiplicand = floor($value / $step);
    $rest         = fmod($value, $step);

    $value = $step * $multiplicand;

    if ($rest > $step / 2) {
        $value += $step;
    }


//Round to nearest 0.05
echo round ($number * 20, 0) / 20;

//Round Up to nearest 0.05
echo ceil ($number * 20) / 20;

//Round Down to nearest 0.05
echo floor ($number * 20) / 20;


Thank you @mauris for the solution to solve my problem on Malaysia GST rounding mechanism. It also works in SQL.

DECLARE @tempTable AS TABLE(Number Decimal(20,4));

INSERT INTO @tempTable VALUES (89.90),(89.91),(89.92),(89.93),(89.94),(89.95),(89.96),(89.97),(89.98),(89.99)

SELECT Number, round(Number * 2, 1) / 2 AS 'Rounded' FROM @tempTable


PHP has the function round() for the PHP 4, PHP 5, PHP 7, PHP 8

https://www.php.net/manual/en/function.round.php

0

精彩评论

暂无评论...
验证码 换一张
取 消