Rounding Mechanism to nearest 0.05 - php

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.my/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

Related

How i can round this number 5.53 always like this: 5.55 in PHP? [duplicate]

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.my/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

Round to 0.5 up and down and if 0 after dot docimal

Hey I have following Problems,
I get ratings and have the average of then but bow I want following:
1,2222222222222 = 1
1,2666666666666 = 1,5
2,3635345435435 = 2.5
2,567435 345345 = 2.5
3.5709 = 3
29,3003453450 = 29
I want all numbers to their most neir .5 but when they have a no decimal then should NOT be displayed 3.0 or 4.0, Just the number without decimals.
at the moment i have this code:
function roundRating($rating) {
return floor($rating * 2) / 2;
}
can someone help me?
greets
Here is a suggestion. See comments for step by step explanation.
<?php
$float = 1.753242342;
// Modulo operator (%) does not return float remainder. Use fmod().
$remainder = fmod($float, 1);
/* Apply rounding logic here.
* It isn't entirely clear to me what your intended behavior is.
* Should 0.75 round up to 1 or down to 0.5?
* I will leave this to you to figure out.
*/
$roundedRemainder = ($remainder >= 0.25)?0.5:0;
$int = $float - $remainder;
$result = $int + $roundedRemainder;
// If remainder is zero, cast to int to remove remainder.
if (fmod($result, 1) == 0)
$result = (int)$result;
echo "Int: " . $int . "<br>";
echo "Remainder: " . $remainder . "<br>";
echo "Rounded remainder: " . $roundedRemainder . "<br>";
echo "Result: " . $result . "<br>";
Outputs:
Int: 1
Remainder: 0.753242342
Rounded remainder: 0.5
Result: 1.5

Round to 5 and 9 php

I'm looking for a formula to round a value to nearest 5 or 9 if the val is less than 5 make 5 if is bigger than 5 make 9.
Example:
$RoundToFive = ceil('232' / 5) * 5;
echo floor($RoundToFive * 2 ) / 2; //Result is 235 Is good
$RoundToNine = ceil('236' / 5) * 5;
echo floor($RoundToNine * 2 ) / 2; //Result is 240 but i need 239
Is there a way to extract always the last 2 digits and convert to 5 or nine ?
Any help is appreciated !
how about:
function funnyRound($number){
$rounded = ceil($number / 5) * 5;
return $rounded%10?$rounded:$rounded-1;
}
This is working
<?php
function roundToDigits($num, $suffix, $type = 'floor') {
$pow = pow(10, floor(log($suffix, 10) + 1));
return $type(($num - $suffix) / $pow) * $pow + $suffix;
};
$RoundToNine = ceil('236' / 5) * 5;
echo roundToDigits($RoundToNine,5);
echo roundToDigits($RoundToNine,9);
You can use any number as $suffix to round to it.
other way, working with strings... :
<?php
function round59($NUMB){
//cast the value to be Int
$NUMB = intval($NUMB);
//Get last number
$last_number = intval(substr($NUMB, -1));
$ROUND_NUMBER = 5;
if($last_number<=5)
$ROUND_NUMBER = 5;
else
$ROUND_NUMBER = 9;
//Remove Last Character
$NUMB = substr($NUMB, 0, -1);
// now concat the results
return intval($NUMB."".$ROUND_NUMBER) ;
}
echo round59(232);
echo round59(236);
?>

No Truncate function in PHP - Options?

I have an algorithm that performs the following calculations:
( ( 0.50 * 0 ) + 7 ) / 10 = 0.70
( ( 0.70 * 10 ) + 9 ) / 20 = 0.80
( ( 0.80 * 20 ) + 7 ) / 30 = 0.7666666667 -> I want this value to truncate to 0.76
So that it may feed into the rest of the calculation as:
4a. ( ( 0.76 * 30 ) + 8 ) / 40 = 0.77
And not to feed in when rounded up two decimal places as 0.77:
4b. ( ( 0.77 * 30 ) + 8 ) / 40 = 0.77
****The following seem to have failed and instead force a round up to 0.77:****
The PHP sptrinf() function: PHP dropping decimals without rounding up
The PHP number_format() function: PHP: show a number to 2 decimal places
The PHP floor() function: Truncate float numbers with PHP
Is there another way?
Is it at all possible to achieve what I want (truncate to two decimal places) with PHP?
Please assist. Many thanks.
UPDATE - SOLVED
Ok, it is working now thanks to dkamins and zneak. I used the floor() approach (I assume I wasn't doing something right in the past). However, now the following happens:
e.g.
(0.86 * 30) + 9 ) / 40 = 0.87 (it should), yet after TRUNC it = 0.86
How is it truncating 0.87 to 0.86? It makes no sense. Is there a way to get it to truncate only if there are more than 2 decimal places?
SOLVED:
$numDecPlace = strlen(substr(strrchr($newRel, "."), 1));
echo '<p>Test: Number of decimal places=' .$numDecPlace. '</p>';
if($numDecPlace > 2) {
$newRel = floor($newRel * 100) / 100; // Truncate to 2dp.
echo '<p>Test: New relationship truncated is $newRel=' .$newRel. '</p>';
}
All the answers given here round the number.
This function worked for me and i hope for you too.
function truncate($number, $decimals)
{
$point_index = strrpos($number, '.');
return substr($number, 0, $point_index + $decimals+ 1);
}
Where $number is the number to truncate and$decimals is the number of decimals you want.
Example: truncate(-38.59540719940386 , 6); returns -38.595407
If you want, check substr's documentation!
You can use PHP's floor function along with some decimal shifting like so:
floor(0.7666666667 * 100) / 100;
how about round()
<?php
echo round(3.4); // 3
echo round(3.5); // 4
echo round(3.6); // 4
echo round(3.6, 0); // 4
echo round(1.95583, 2); // 1.96
echo round(1241757, -3); // 1242000
echo round(5.045, 2); // 5.05
echo round(5.055, 2); // 5.06
?>
To do this accurately for both +ve and -ve numbers you need use:
- the php floor() function for +ve numbers
- the php ceil() function for -ve numbers
function truncate_float($number, $decimals) {
$power = pow(10, $decimals);
if($number > 0){
return floor($number * $power) / $power;
} else {
return ceil($number * $power) / $power;
}
}
the reason for this is that floor() always rounds the number down, not towards zero.
ie floor() effectively rounds -ve numbers towards a larger absolute value
eg floor(1.5) = 1 while floor(-1.5) = 2
Therefore for the truncate method using multiply by power, round, then divide by power:
- floor() only works for positive numbers
- ceil() only works for negative numbers
To test this, copy the following code into the editor of http://phpfiddle.org/lite (or similar):
<div>Php Truncate Function</div>
<br>
<?php
function truncate_float($number, $places) {
$power = pow(10, $places);
if($number > 0){
return floor($number * $power) / $power;
} else {
return ceil($number * $power) / $power;
}
}
// demo
$lat = 52.4884;
$lng = -1.88651;
$lat_tr = truncate_float($lat, 3);
$lng_tr = truncate_float($lng, 3);
echo 'lat = ' . $lat . '<br>';
echo 'lat truncated = ' . $lat_tr . '<br>';
echo 'lat = ' . $lng . '<br>';
echo 'lat truncated = ' . $lng_tr . '<br><br>';
// demo of floor() on negatives
echo 'floor (1.5) = ' . floor(1.5) . '<br>';
echo 'floor (-1.5) = ' . floor(-1.5) . '<br>';
?>
I used would use the round() function as mentioned by Kartikey. You can find more information here at PHP.Net
float round ( float $val [, int $precision = 0 [, int $mode = PHP_ROUND_HALF_UP ]] )
Fissh

PHP formula needed to calculate a simple format

I am trying to take an amount and convert it to a units type format...
For example:
( note: don't worry about the dollar sign )
Total is $400
I need to display it as 4 * 100
Another Example
Total is $450
I need to display it as 4 * 100 | 50 * 1
So another words there are only 100 and 1 units.
I was thinking for 3 hours already and nothing seems to come to mind...Perhaps someone out there has done something similar and already know the answer?
Hoping I am not doing your homework. Try this:
$num = 450;
$ones = $num % 100;
$hundreds = floor($num / 100);
echo "$hundreds * 100 | $ones * 1";
Here's a simple implementation
$amount = 450;
$hundreds = floor($amount / 100);
$ones = $amount % 100;
$string = array();
if( $hundreds )
$string[] = "$hundreds * 100";
if( $ones )
$string[] = "$ones * 1";
echo implode(' | ', $string);
Check out the modulus (%) operator
Here's a simple solution which will only show the units present, you can get rid of the array/join stuff if you always need to show both units:
$total = 400;
$out = array();
$hundreds = floor($total / 100);
if ($hundreds) {
$out[] = $hundreds . ' * 100';
}
$ones = $total % 100;
if ($ones) {
$out[] = $ones . ' * 1';
}
echo join(' | ', $out);
Use the modulus operator to break down the number (this kind of thing is good to learn how to do because you'll need it for many other units conversion tasks like seconds -> minutes & seconds conversion):
$value=450;
$ones = $value % 100;
$hundreds = floor($value / 100);
echo "$hundreds * 100 | $ones * 1\n";

Categories