Rounding Mechanism to nearest 0.05
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:
- Divide by 0.05
- or multiply by (1 / 0.05)
- Round to nearest integer
- 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
精彩评论