What would be the solution to have:
7.1 => 7
7.5 => 7
7.8 => 8
So I need to round number or floor depending on the number after the comma.
How to do that?
Thanks.
You should be able to use the constant, PHP_ROUND_HALF_DOWN, to have the round function round down when it is half way.
echo round(7.1, 0, PHP_ROUND_HALF_DOWN) . "\n";
echo round(7.5, 0, PHP_ROUND_HALF_DOWN) . "\n";
echo round(7.8, 0, PHP_ROUND_HALF_DOWN) . "\n";
Output:
7
7
8
From the manual:
Round val down to precision decimal places towards zero, when it is half way there. Making 1.5 into 1 and -1.5 into -1.
PHP Demo: https://eval.in/427706
One way to do this is to split the value at the decimal (or comma? your example is using decimals) and test the trailing number to see whether you want to use floor or ceiling.
$test = 7.6
$arrayTest = explode(".",$test);
if(isset($arrayTest[1]) && $arrayTest[1] > 5) {
//do something
} else {
//do something else
}
Related
I am having a variety of long numbers and I am trying to write a function to format them correctly. Can someone help me out?
I already tried "number_format()" and "round()" but that doesn't solve my problems..
I would like to round it like following:
1024.43 --> 1,024.43
0.000000931540 --> 0.000000932
0.003991 --> 0.00399
0.3241 --> 0.324
1045.3491 --> 1,045.35
So that means, If number is bigger than "0" it should round to 2 decimal places and add thousands seperator (like 6,554.24) AND if number less than "1" it should round to 3 digits whenever numbers appear after the zeros (for example 0.0003219 to 0.000322 OR 0.2319 to 0.232)
EDIT:
The same should apply to "-" values. For example:
-1024.43 --> -1,024.43
-0.000000931540 --> -0.000000932
-0.003991 --> -0.00399
-0.3241 --> -0.324
-1045.3491 --> -1,045.35
Adapting from https://stackoverflow.com/a/48283297/2469308
handle this in two separate cases.
for numbers between -1 and 1; we need to calculate the number of digits to round. And then, using number_format() function we can get the result.
for else, simply use number_format() function with decimal digits set to 2.
Try the following:
function customRound($value)
{
if ($value > -1 && $value < 1) {
// define the number of significant digits needed
$digits = 3;
if ($value >= 0) {
// calculate the number of decimal places to round to
$decimalPlaces = $digits - floor(log10($value)) - 1;
} else {
$decimalPlaces = $digits - floor(log10($value * -1)) - 1;
}
// return the rounded value
return number_format($value, $decimalPlaces);
} else {
// simply use number_format function to show upto 2 decimal places
return number_format($value, 2);
}
// for the rest of the cases - return the number simply
return $value;
}
Rextester DEMO
$x = 123.456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 1.23456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 0.0123456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 0.0000123456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 0.000000123456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
$x = 0.00000000123456;
echo number_format($x, max(2, 3 - ceil(log10(abs($x))))) . "\n";
Output:
123.45
1.23
0.0123
0.0000123
0.000000123
0.00000000123
Basically this always keeps a minimal of 2 decimal digits up to 3 significant digits.
However, because of the way floating point is handled internally (as power of 2 and not 10), there are some catches. Numbers like 0.1 and 0.001 and so forth can't be stored precisely, so they are actually stored as 0.09999999... or things like that. In cases like this it may seem like it is computing things wrong and give you answers with more significant digits than it should.
You can try to counteract this phenomena by allowing an error margin to the formula:
number_format($x, max(2, 3 - ceil(log10(abs($x))) - 1e-8))
But this may cause other undesirable effects. You will have to make tests.
Is there a way with number_format() to leave out decimal places if the number is not a float/decimal?
For example, I would like the following input/output combos:
50.8 => 50.8
50.23 => 50.23
50.0 => 50
50.00 => 50
50 => 50
Is there a way to do this with just a standard number_format()?
You can add 0 to the formatted string. It will remove trailing zeros.
echo number_format(3.0, 1, ".", "") + 0; // 3
A Better Solution: The above solution fails to work for specific locales. So in that case, you can just type cast the number to float data type. Note: You might loose precision after type casting to float, bigger the number, more the chances of truncating the number.
echo (float) 3.0; // 3
Ultimate Solution: The only safe way is to use regex:
echo preg_replace("/\.?0+$/", "", 3.0); // 3
echo preg_replace("/\d+\.?\d*(\.?0+)/", "", 3.0); // 3
Snippet 1 DEMO
Snippet 2 DEMO
Snippet 3 DEMO
If you want to use whitespace here is better solution
function real_num ($num, $float)
{
if (!is_numeric($num) OR is_nan($num) ) return 0;
$r = number_format($num, $float, '.', ' ');
if (false !== strpos($r, '.'))
$r = rtrim(rtrim($r, '0'), '.');
return $r;
}
Use:
$a = 50.00;
$a = round($a, 2);
Even though the number has 2 zeros trailing it, if you round it, it won't show the decimal places, unless they have some kind of value.
So 50.00 rounded using 2 places will be 50, BUT 50.23 will be 50.23.
Unless you specify at which point to round up or down, it won't change your decimal values. So just use default round()
php function round not working correctly.
I have number 0.9950.
I put code:
$num = round("0.9950", 2);
And I get 1.0? Why?? Why I can't get 0.99?
You can add a third parameter to the function to make it do what you need.
You have to choose from one of the following :
PHP_ROUND_HALF_UP
PHP_ROUND_HALF_DOWN
PHP_ROUND_HALF_EVEN
PHP_ROUND_HALF_ODD
This constants are easy enough to understand, so just use the adapted one :)
In your example, to get 0.99, you'll need to use :
<?php echo round("0.9950", 2, PHP_ROUND_HALF_DOWN); ?>
DEMO
When you round 0.9950 to two decimal places, you get 1.00 because this is how rounding works. If you want an operation which would result in 0.99 then perhaps you are looking for floating point truncation. One option to truncate a floating point number to two decimal places is to multiply by 100, cast to integer, then divide again by 100:
$num = "0.9950";
$output = (int)(100*$num) / 100;
echo $output;
0.99
This trick works because after the first step 0.9950 becomes 99.50, which, when cast to integer becomes just 99, discarding everything after the second decimal place in the original number. Then, we divide again by 100 to restore the original number, minus what we want truncated.
Demo
Just tested in PHP Sandbox... PHP seems funny sometimes.
<?php
$n = 16.90;
echo (100*$n)%100, "\n"; // 89
echo (int)(100*$n)%100, "\n"; // 89
echo 100*($n - (int)($n)), "\n"; // 90
echo (int)(100*($n - (int)($n))), "\n"; // 89
echo round(100*($n - (int)($n))), "\n"; // 90
is there any way you can round to lower with any number lower than .50 including .50?
For example:
round(1.49) => 1
round(1.51) => 2
round(1.50) => 2
Is there any way to make it like this:
round(1.49) => 1
round(1.51) => 2
round(1.50) => 1
Use PHP_ROUND_HALF_DOWN flag
echo round(1.49, 0, PHP_ROUND_HALF_DOWN);
echo PHP_EOL;
echo round(1.50, 0, PHP_ROUND_HALF_DOWN);
echo PHP_EOL;
echo round(1.51, 0, PHP_ROUND_HALF_DOWN);
Subtract 0.5 from your number and use ceil on the result.
E.g. ceil(1.51 - 0.5) = 2, ceil(1.50 - 0.5) = 1
It's a perversion of the idiomatic way of doing rounding without a round function. The subtraction caters for your wanting to round the 1/2 way point downwards. Extra checks necessary for negatives.
Is it possible to round a number where if it's .5, just leave it, anything below .5 round down, anything above .5 round up?
For example:
5.0 * 1.35 = 6.75 // leave it
5.2 * 1.35 = 7.02 // round down to 7.00
5.5 * 1.35 = 7.56 // round up to 8.00
I've formatted with round($n,0, PHP_ROUND_HALF_UP) where $n is the product from the above calc , which leaves 6.75 but returns 7.02 for the next one. I also tried round($n,-1, PHP_ROUND_HALF_UP) which gives me the 7.00 on the second calc but then of course won't return a 6.75 for the first, instead it returns 680.
This is a ticket markup calculation where the user enters the first number and is multiplied by the second. I actually remove the decimal because they don't want to see it, and they want this sort of customized rounding on the result.
function myround($num, $prec) {
$rhu = round($num, $prec, PHP_ROUND_HALF_UP);
$rhd = round($num, $prec, PHP_ROUND_HALF_DOWN);
return ($rhu + $rhd) / 2;
}
Works for any precision you like. For hundreth's place, as in the example, $prec would need to be 2.
The only way to determine the value of the last non-zero digit of a given floating point number in PHP is to convert it to a string.
$str = (string) $float;
$result = ($str[strlen($str) - 1] == 5) ? $float : round($float);
Example
Of course, no matter what you do it will be subject to a small margin of error because of the floating point precision issue.
$n = round($n, 2);
if($n % .05 != 0 || $n % .1 == 0)
{
$n = round($n);
}
Does this work for you? I'm assuming the 5 you speak of is the hundredth digit, and if it's not 5 then you want a whole number.