Rounding last decimal place to 0? - php

I tried round, ceil and floor, but they do not seem to do what I want (or I dont see the wood for the trees :-))
This is what I want:
1.44 --> 1.40
1.23 --> 1.20
3.50 --> 4.00
2.48 --> 2.50
...
I did not find a way to achieve that. Should be possible?
Thanks!

You can combine round() and number_format():
For example:
$number = 1.44;
number_format(round($number, 1), 2, '.', ''); // 1.40

I'd use sptrintf to format the number to 1 decimal, then append a 0 behind it:
sprintf('%0.1f0', $test)
Test cases:
<?php
foreach ([ 1.44, 1.23, 3.50, 2.48 ] as $test) {
$rounded = sprintf('%0.1f0', $test);
var_dump($rounded);
}
string(4) "1.40"
string(4) "1.20"
string(4) "3.50"
string(4) "2.50"
Try it online!
As string, since trailing 0 on a float are removed by PHP

I don't think there is a native php function already doing what you want. We will need to do it ourself. First by finding the depth of the decimal part, then by rounding depending on depth.
<?php
function roundToSecondLastDigit(float $number): float{
$decimal = $number - intval($number);
$depth = strlen((string) $decimal) - 2;
return round($number, $depth - 1);
}
echo roundToSecondLastDigit(1.44) . "\n"; //1.4
echo roundToSecondLastDigit(1.23) . "\n"; //1.2
echo roundToSecondLastDigit(3.50) . "\n"; //4
echo roundToSecondLastDigit(2.48) . "\n"; //2.5
You can print your number with the precision you want with number_format then.
echo number_format(roundToSecondLastDigit(2.48), 2, '.', ''); //2.50

Related

Use round or floor depending the number after the comma

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
}

number_format rounding up number that end with 5 decimal

Is there a way to make number_format not to round up numbers that end up with a "5" decimal?
echo number_format(25.58,1); // 25.6 - OK
echo number_format(85.72,1); // 85.7 - OK
echo number_format(26.25,1); // 26.3 - WHY? 26.2 needed here.
Note: I'm not asking this
Instead of using number_format() use the round function. You can specify how you want it to round.
echo round(25.58, 1, PHP_ROUND_HALF_DOWN); // 25.6
echo round(85.72, 1, PHP_ROUND_HALF_DOWN); // 85.7
echo round(26.25, 1, PHP_ROUND_HALF_DOWN); // 26.2
It's unclear on what you are trying to achieve. Based on your comment of 'ignoring' numbers that end in five i have mocked up a very basic quick function that does this
echo format_numbers(25.58,1); // 25.6
echo format_numbers(85.72,1); // 85.7
echo format_numbers(26.25,1); // 26.2
function format_numbers($number, $decimal)
{
if(substr($number, -1) == '5'){
$number = $number - 0.1;
}
return number_format($number, $decimal);
}
This example is for PHP versions that do not support the prefered method of round(26.25, 1, PHP_ROUND_HALF_DOWN). The above example will deduct 0.1 from the number thus forcing number_format() to round down.

Is there an equivalent for toPrecision() in PHP?

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

PHP number_format is rounding?

I have a price "0,10" or "00000,10"
Now when i try
number_format($price, 2, ',', '')
I get 0,00.
How can i fix this? I want 0,10 $.
I don't want rounding.
Or when i have 5,678, i get 5,68. But i want 5,67.
Several people have mentioned rounding it to 3 and then dropping the last character. This actually does not work. Say you have 2.9999 and round it to 3 it's 3.000.
This is still not accurate, the best solution is this:
$price = '5.678';
$dec = 2;
$price = number_format(floor($price*pow(10,$dec))/pow(10,$dec),$dec);
What this does is takes the price and multiplies it by 100 (10^decimal) which gives 567.8, then we use floor to get it to 567, and then we divide it back by 100 to get 5.67
You can increase the size of the number before rounding down with floor:
$price = floor($price * 100) / 100;
$formatted = number_format($price, 2, ',', '');
Another solution, which may give better precision since it avoids floating-point arithmetic, is to format it with three decimals and throw away the last digit after formatting:
$formatted = substr(number_format($price, 3, ',', ''), 0, -1);
you should convert comma-filled number back to normal decimal before with str_replace.
$number = str_replace(",", ".", $number);
and then you can use number_format
"00000,10" is a string. You should a decimal point. To get the desired behaviour, you could use:
echo substr(number_format(str_replace(',', '.', $price), 3, ',', ''), 0, -1);
Use this (needs activated intl PHP extension)
$numberFmtCurrency = new NumberFormatter('de_AT', NumberFormatter::CURRENCY);
$numberFmtCurrency->setAttribute(NumberFormatter::ROUNDING_INCREMENT, 0);
$numberFmtCurrency->formatCurrency(328.13, 'EUR'); // prints € 328.13 (and not 328.15)
If you are literally just wanting to clear leading zeroes and just limit the length, rather than round to a certain amount of decimal places, a more generalised solution could be this function:
function cutafter($string,$cutpoint,$length)
{
$temp = explode($cutpoint,$string);
$int = $temp[0];
$sub = $temp[1];
return number_format($int,0).','.substr($sub,0,$length);
}
Example:
$number = "005,678";
$answer = cutafter($number,",",2);
$answer now equals "5,67"
Just before number_format is executed the string "0,10" is converted by php to an number. because php always uses the engish notation the it won't look after the comma.
echo "4 apples" + 2;
output: 6
The " apples" part is ignored just as your ",10" is ignored.
Converting the "," to a "." allows php to see the other digits.
$price = str_replace(',', '.', '0,10');
number_format($price, 2, ',', '');
My problem was that html validator error messege thar number_format() argument is not double.
I solved this error message by placing floatval for that argument like number_format(floatval($var),2,'.',' ') and that is working good.
function format_numeric($value) {
if (is_numeric($value)) { // is number
if (strstr($value, ".")) { // is decimal
$tmp = explode(".", $value);
$int = empty($tmp[0]) ? '0' : $tmp[0];
$dec = $tmp[1];
$value = number_format($int, 0) . "." . $dec;
return $value;
}
$value = number_format($value);
return $value;
}
return $value; // is string
}
Unit Testing:
Passed / 1100000 => 1,100,000
Passed / ".9987" => .9987
Passed / 1100.22 => 1,100.22
Passed / 0.9987 => 0.9987
Passed / .9987 => 0.9987
Passed / 11 => 11
Passed / 11.1 => 11.1
Passed / 11.1111 => 11.1111
Passed / "abc" => "abc"
See this answer for more details.
function numberFormat($number, $decimals = 0, $decPoint = '.' , $thousandsSep = ',')
{
$negation = ($number < 0) ? (-1) : 1;
$coefficient = pow(10, $decimals);
$number = $negation * floor((string)(abs($number) * $coefficient)) / $coefficient;
return number_format($number, $decimals, $decPoint, $thousandsSep);
}

How do I echo a variable thats a double, but only show the decimal places if they're needed?

I have some double fields in my database and when echoing the fields out in my php I get .00 at the end of the values.
How do I get the .00 not to display, but display if there is a value?
You can use str_replace to remove the ".00" from the values.
$value = 10.00;
echo str_replace('.00', '', $value); // 10
$value = 10.52;
echo str_replace('.00', '', $value); // 10.52
echo (int)$double;
will simply strip off the decimal places. if you merely want to hide 'zero' decimals (10.00 -> 10), but leave non-zero decimals (10.1 -> 10.1), then you'd need to do some processing:
echo preg_replace('/\.0+$/', '', $double);
which would handle any number of zeroes after the decimal place, but leave non-zeroes in place.
if (fmod($number, 1) == 0)
{
$number = intval($number);
}
else
{
$number = round($number, 2);
}
Or just use round() [# ideone.com]:
var_dump(round($number = 5.00, 2)); // 5
var_dump(round($number = 5.01, 2)); // 5.01
For an arbitrary number of 0s at the end of the number:
$number = rtrim($number,".0");
Examples:
Input : 1.00
Result: 1
Input : 1.25
Result: 1.25
Input : 1.40
Result: 1.4
Input : 1.234910120000
Result: 1.23491012
select number,if(number % 1 = 0,cast(number as unsigned),number)
from table

Categories