I need a PHP function that will take a float and round it down to the nearest half (x.0 or x.5). I found other functions that will round to the nearest fraction, but they round both ways.
The function I need can only round down.
Examples
7.778 -> 7.5
7.501 -> 7.5
7.49 -> 7.0
7.1 -> 7.0
$x = floor($x * 2) / 2;
I'm assuming PHP has a floor function: floor($num * 2) / 2 ought to do it.
A easy solution is to use modulo operator (fmod() function), like this :
function roundDown($number, $nearest){
return $number - fmod($number, $nearest);
}
var_dump(roundDown(7.778, 0.5));
var_dump(roundDown(7.501, 0.5));
var_dump(roundDown(7.49, 0.5));
var_dump(roundDown(7.1, 0.5));
And the result :
The advantage it's that work with any nearest number (0.75, 22.5, 3.14 ...)
You can use the same operator to roundUp :
function roundUp($number, $nearest){
return $number + ($nearest - fmod($number, $nearest));
}
var_dump(roundUp(7.778, 0.5));
var_dump(roundUp(7.501, 0.5));
var_dump(roundUp(7.49, 0.5));
var_dump(roundUp(7.1, 0.5));
You can do it on that way round($number / 5, 1) * 5 the second parameter in the round() is the precision.
Example with $number equal to 4.6, 4.8 and 4.75
>>> round(4.6 / 5, 1) * 5;
=> 4.5
>>> round(4.8 / 5, 1) * 5;
=> 5.0
>>> round(4.75 / 5, 1) * 5;
=> 5.0
If you want you can round() down too like round($number, 1, PHP_ROUND_HALF_DOWN) check the documentation for more information https://www.php.net/manual/en/function.round.php
echo round($val*2) / 2; // Done
From my job's requirements. I put an function to do this. Hope you can view it as a reference:
function round_half_five($no) {
$no = strval($no);
$no = explode('.', $no);
$decimal = floatval('0.'.substr($no[1],0,2)); // cut only 2 number
if($decimal > 0) {
if($decimal <= 0.5) {
return floatval($no[0]) + 0.5;
} elseif($decimal > 0.5 && $decimal <= 0.99) {
return floatval($no[0]) + 1;
}
} else {
return floatval($no);
}
}
Related
I have this code
<?php echo round(0.572,2,PHP_ROUND_HALF_UP);?>
I want to round two decimals to half up, I expect a value as 0.58...
but the above code print 0.57
How can I do this?
if you expect 0,58 you don't have to use a "half round" but the ceil function
$v = 0.575;
echo ceil($v * 100) / 100; // show 0,58
The value 0.572 can not be rounded up to 0.58, because the third decimal, 2, is less than half (or 5). If you were doing round(0.575, 2, PHP_ROUND_HALF_UP) you would get 0.58. In this case 0.57 is the correct rounded value.
If you wish to always round up from the 3rd decimal, regardless of its value you could use ciel() instead, but it requires a little additional math. A simple function to demonstrate rounding up always would be...
function forceRoundUp($value, $decimals)
{
$ord = pow(10, $decimals);
return ceil($value * $ord) / $ord;
}
echo forceRoundUp(0.572, 2); // 0.58
echo forceRoundUp(0.57321, 4); // 0.5733
function round_up($value, $places)
{
$mult = pow(10, abs($places));
return $places < 0 ?
ceil($value / $mult) * $mult :
ceil($value * $mult) / $mult;
}
echo round_up(0.572,2);
Hope this will work for you!!
xx.01 and xx.02 go to xx.00
xx.03 and xx.04 go to xx.05
xx.06 and xx.07 go to xx.05
xx.08 and xx.09 go to xx.10
xx.11 and xx.12 go to xx.10
xx.13 and xx.14 go to xx.15
I need the below format behind the dot.
0.05 / 0.10 / 0.15/ 0.20 / 0.25 / 0.30 / 0.35 / 0.40 etc….
Can anyone give me a function in PHP to convert the number after the dot to the expected value?
function soRound($a, $to=0.05) {
return round($a / $to) * $to ;
}
This rounds as you describe with no default second argument
i.e soRound(1.07); returns 1.05
You need to round, but you can only use round to round to the nearest tenth. You want to round to the nearest twentieth. The solution is to multiply by 2, round to the nearest tenth, divide by 2, and format as needed:
$data = [0, 0.01, 0.07, 0.09, 1.56, 1.73, 3.14159];
foreach ($data as $num) {
$num = round($num * 2, 1) / 2;
echo number_format($num, 2) . "\n";
}
Output:
0.00
0.00
0.05
0.10
1.55
1.75
3.15
Here's a working demo.
In function form:
function roundToNearest05($num) {
return round($num * 2, 1) / 2;
}
// or, more generically, this:
function roundTo($num = 0, $nearest = 0.05) {
return round($num / $nearest) * $nearest;
}
For example a number to 3 significant figures would be as follows
12345 => 12300
0.12345 => 0.123
0.012345 => 0.0123
There's nothing built in to round to a given number of significant figures (as opposed to a given number of digits.) Math to the rescue!
function toPrecision($number, $precision) {
if ($number == 0) return 0;
$exponent = floor(log10(abs($number)) + 1);
$significand =
round(
($number / pow(10, $exponent))
* pow(10, $precision)
)
/ pow(10, $precision);
return $significand * pow(10, $exponent);
}
$numbers = [
12345,
.12345,
.012345,
];
foreach($numbers as $number) {
echo toPrecision($number, 3), "\n";
}
Output:
12300
0.123
0.0123
In php, you could use round() function. It accepts two parameters, the number and precision, such as
echo round(12345, -2); # will result in 12300
echo round(0.12345, 3); # will result in 0.123
See the php manual on round() for more information.
There are several functions you can use for math operations. Here are a few examples
// 0.12345 => 0.123 - round half down
$result = round(0.12345, 3, PHP_ROUND_HALF_DOWN)
// 0.12345 => 0.124 - natural rounding
$result = round(0.12345. 3);
// 12345 => 12300
$result = round(12345, -2, PHP_ROUND_HALF_DOWN);
The round() function rounds integers by the given precision. Please respect the natural sorting. Higher than 5 means rounding up as far as you don 't mention the PHP_ROUND_HALF_DOWN constant.
You can use number_format() to achieve what you need.
$value = 0.12345;
$output = number_format($value, 3);
echo $output;
This will return: 0.123
Or you could wrap this withing a foreach loop if you need to go through an array, or alternatively create your own function to accept an integer and return the formatted value.
function formatNumber($int){
$number = number_format($int, 3);
return $number;
}
Or alternatively look at the link below to see if there is any other way you want to do this.
PHP.NET PAGE
This question already has answers here:
Truncate float numbers with PHP
(14 answers)
Closed 11 months ago.
I need to round down a decimal in PHP to two decimal places so that:
49.955
becomes...
49.95
I have tried number_format, but this just rounds the value to 49.96. I cannot use substr because the number may be smaller (such as 7.950). I've been unable to find an answer to this so far.
Any help much appreciated.
This can work: floor($number * 100) / 100
Unfortunately, none of the previous answers (including the accepted one) works for all possible inputs.
1) sprintf('%1.'.$precision.'f', $val)
Fails with a precision of 2 : 14.239 should return 14.23 (but in this case returns 14.24).
2) floatval(substr($val, 0, strpos($val, '.') + $precision + 1))
Fails with a precision of 0 : 14 should return 14 (but in this case returns 1)
3) substr($val, 0, strrpos($val, '.', 0) + (1 + $precision))
Fails with a precision of 0 : -1 should return -1 (but in this case returns '-')
4) floor($val * pow(10, $precision)) / pow(10, $precision)
Although I used this one extensively, I recently discovered a flaw in it ; it fails for some values too. With a precision of 2 : 2.05 should return 2.05 (but in this case returns 2.04 !!)
So far the only way to pass all my tests is unfortunately to use string manipulation. My solution based on rationalboss one, is :
function floorDec($val, $precision = 2) {
if ($precision < 0) { $precision = 0; }
$numPointPosition = intval(strpos($val, '.'));
if ($numPointPosition === 0) { //$val is an integer
return $val;
}
return floatval(substr($val, 0, $numPointPosition + $precision + 1));
}
This function works with positive and negative numbers, as well as any precision needed.
Here is a nice function that does the trick without using string functions:
<?php
function floorp($val, $precision)
{
$mult = pow(10, $precision); // Can be cached in lookup table
return floor($val * $mult) / $mult;
}
print floorp(49.955, 2);
?>
An other option is to subtract a fraction before rounding:
function floorp($val, $precision)
{
$half = 0.5 / pow(10, $precision); // Can be cached in a lookup table
return round($val - $half, $precision);
}
I think there is quite a simple way to achieve this:
$rounded = bcdiv($val, 1, $precision);
Here is a working example. You need BCMath installed but I think it's normally bundled with a PHP installation. :) Here is the documentation.
function roundDown($decimal, $precision)
{
$sign = $decimal > 0 ? 1 : -1;
$base = pow(10, $precision);
return floor(abs($decimal) * $base) / $base * $sign;
}
// Examples
roundDown(49.955, 2); // output: 49.95
roundDown(-3.14159, 4); // output: -3.1415
roundDown(1000.000000019, 8); // output: 1000.00000001
This function works with positive and negative decimals at any precision.
Code example here: http://codepad.org/1jzXjE5L
Multiply your input by 100, floor() it, then divide the result by 100.
You can use bcdiv PHP function.
bcdiv(49.955, 1, 2)
Try the round() function
Like this: round($num, 2, PHP_ROUND_HALF_DOWN);
For anyone in need, I've used a little trick to overcome math functions malfunctioning, like for example floor or intval(9.7*100)=969 weird.
function floor_at_decimals($amount, $precision = 2)
{
$precise = pow(10, $precision);
return floor(($amount * $precise) + 0.1) / $precise;
}
So adding little amount (that will be floored anyways) fixes the issue somehow.
Use formatted output
sprintf("%1.2f",49.955) //49.95
DEMO
You can use:
$num = 49.9555;
echo substr($num, 0, strpos($num, '.') + 3);
function floorToPrecision($val, $precision = 2) {
return floor(round($val * pow(10, $precision), $precision)) / pow(10, $precision);
}
An alternative solution using regex which should work for all positive or negative numbers, whole or with decimals:
if (preg_match('/^-?(\d+\.?\d{1,2})\d*$/', $originalValue, $matches)){
$roundedValue = $matches[1];
} else {
throw new \Exception('Cannot round down properly '.$originalValue.' to two decimal places');
}
Based on #huysentruitw and #Alex answer, I came up with following function that should do the trick.
It pass all tests given in Alex's answer (as why this is not possible) and build upon huysentruitw's answer.
function trim_number($number, $decimalPlaces) {
$delta = (0 <=> $number) * (0.5 / pow(10, $decimalPlaces));
$result = round($number + $delta, $decimalPlaces);
return $result ?: 0; // get rid of negative zero
}
The key is to add or subtract delta based on original number sign, to support trimming also negative numbers.
Last thing is to get rid of negative zeros (-0) as that can be unwanted behaviour.
Link to "test" playground.
EDIT: bcdiv seems to be the way to go.
// round afterwards to cast 0.00 to 0
// set $divider to 1 when no division is required
round(bcdiv($number, $divider, $decimalPlaces), $decimalPlaces);
sprintf("%1.2f",49.955) //49.95
if you need to truncate decimals without rounding - this is not suitable, because it will work correctly until 49.955 at the end, if number is more eg 49.957 it will round to 49.96
It seems for me that Lght`s answer with floor is most universal.
Did you try round($val,2) ?
More information about the round() function
I'm creating this rating system using 5-edged stars. And I want the heading to include the average rating. So I've created stars showing 1/5ths. Using "1.2" I'll get a full star and one point on the next star and so on...
But I haven't found a good way to round up to the closest .2... I figured I could multiply by 10, then round of, and then run a switch to round 1 up to 2, 3 up to 4 and so on. But that seems tedious and unnecessary...
round(3.78 * 5) / 5 = 3.8
A flexible solution
function roundToNearestFraction( $number, $fractionAsDecimal )
{
$factor = 1 / $fractionAsDecimal;
return round( $number * $factor ) / $factor;
}
// Round to nearest fifth
echo roundToNearestFraction( 3.78, 1/5 );
// Round to nearest third
echo roundToNearestFraction( 3.78, 1/3 );
function round2($original) {
$times5 = $original * 5;
return round($times5) / 5;
}
So your total is 25, would it be possible to not use floats and use 1->25/25? That way there is less calculations needed... (if any at all)
Why is everyone giving solutions that require a deeper inspection or conversion? Want 0.2? Then:
round($n / 0.2) * 0.2; // $n = 3.78 / 0.2 = 18.9 (=) 19 * 0.2 = 3.8 //
Want 5? Then:
round($n / 5) * 5; // $n = 17 / 5 = 3.4 (=) 3 * 5 = 15 //
It's as simple as that.