How to Present a floating point number using php - php

I have a price database that stores numbers as floating point. These are presented on a website. Prices can be in the format.
x.x (e.g. 1.4)
x.xx (e.g. 1.99)
x.xxx (e.g. 1.299) <-- new price format
I used to use the string format or %.2f to standardize the prices to two decimal places but now I need to show 3 as well but only if the price is 3 decimal place long.
e.g. 1.4 would display 1.40
1.45 would display 1.45
1.445 would display 1.445
The above formats would be the desired output for the given input.
using %.3f shows all with 3 digits.
e.g. 1.4 would display 1.400
1.45 would display 1.450
1.445 would display 1.445
But that is not what i want does anyone know the best way to do the following.
i.e. any number should display 2 decimal places if it has 0 1 or 2 decimal places
if it has 3 or more decimal places it should display 3 decimal places

I would just format it to three places, then trim a final 0.
$formatted = number_format($value, 3, ".", "");
if (substr($formatted, -1) === "0") $formatted = substr($formatted, 0, -1);

Use this dude
number_format($data->price, 0, ',', '.');
http://php.net/manual/en/function.number-format.php

Here is what I did due to the need to cope with some special cases I had in the app.
count the number of dec places ($prices is a float from the database).
format based on the count in the places using a switch statement.
For all cases with less than 3 decimal places format with 2 (except zero)
For all other case format with 3.
$decimals = strlen(substr(strrchr($price,"."),1));
switch ($decimals) {
case 0: {
if ($price != 0) {
$price = number_format($price),2);
}
break;
}
case 1: {
$price = number_format($price),2);
break;
}
case 2: {
$price = number_format($price),2);
break;
}
default: {
$price = number_format($price),3); // three dec places all other prices
break;
}
}
Thanks for the help...

Related

number_format() php remove trailing zeros

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()

2 digit precision PHP

I am trying to do a 2 digit precision in PHP Laravel project but it doesnt work. I have the value 1234666.6666667 that I want to make 1234666.66 but all the results I've seen in here or/and in other search pages.
This is my code:
$value = 1234666.6666667;
return round($value,2);
any other solution?
EDIT:
As I see, you actually want to floor number to 2 decimal points, not to round it, so this answer could help you:
$value = 1234666.6666667;
floor($value * 100) / 100; // returns 1234666.66
If you want 3 decimal points you need to multiple and divide with 1000, for 4 - with 10000 and etc.
You can use number_format, it convert value to string though, so you lose real float value:
$value = 1234666.6666667;
echo number_format($value, 2, '.', ''); // prints 1234666.67
Use this function.
function truncate($i) {
return floor($i*100) / 100.0;
}
Then you can do
$value = truncate(123.5666666); // 123.56
A pragmatic way is to use round($value - 0.05, 2), but even that gets you into hot water with some edge cases. Floating point numbers just don't round well. It's life I'm afraid. The closest double to 1234666.66 is
1234666.65999999991618096828460693359375
That's what $value will be after applying my formula! Really, if you want exact decimal precision, then you need to use a decimal type. Else use integer types and work in multiples of 100.
For the former choice, see http://de2.php.net/manual/en/ref.bc.php
$value = bcadd($value, 0, 2); // 1234666.6666667 -> 1234666.66
Another more exotic way to solve this issue is to use bcadd() with a dummy value for the $right_operand of 0,
This will give you 2 number after decimal.

php Determine a float variable has two decimal places

MySQL data imoprt mongo database.
price float(15,2) in mysql, mongo is not float(15,2).
I want to Determine a var $price have two decimal places.
eg. 100.00 is right, 100 or 100.0 is wrong.
eg.1
$price = 100.00;
$price have two decimal, it's right.
eg.2
$price = 100.0;
$price have not two decimal, it's wrong.
I like to use Regular Expressions to do these things
function validateTwoDecimals($number)
{
if(preg_match('/^[0-9]+\.[0-9]{2}$/', $number))
return true;
else
return false;
}
(Thanks to Fred-ii- for the corrections)
Everybody is dancing around the fact that floating point numbers don't have a number of decimal places in their internal representation. i.e. in float 100 == 100.0 == 100.00 == 100.000 and are all represented by the same number, effectively 100 and is stored that way.
The number of decimal places in this example only has a context when the number is represented as a string. In which case any string function that counts the number of digits trailing the decimal point could be used to check.
number_format($price, $numberOfDecimalDigits) === $price;
or
strrpos($price, '.') === strlen($price) - 1 - $numberOfDecimalDigits;
Trivia: $price should not be called a "float variable". This is a string that happens to represent a float value. 100.00 as a float has zero decimal digits, and 100.00 === 100 as float :
$price = 100.00;
echo $price; // output: 100
$price2 = (float)100;
echo $price === $price2; // ouput: 1
In order for this to work, the number will need to be wrapped in quotes.
With the many scripts I've tested, using $price = 100.00; without quotes did not work, while $price = 100.10; did, so this is as best as it gets.
<?php
$number = '100.00';
echo $number.'<br>';
$count = explode('.',$number);
echo 'The number of digits after the decimal point is: ' . strlen($count[1]);
if(strlen($count[1]) == 2){
echo "<br>";
echo "There is 2 decimal points.";
}
else{
echo "<br>";
echo "There is not 2 decimal points.";
}
After you format the value, you can check with simply splitting the value as string into 2 parts, for example with explode ...
$ex=explode('.',$in,2); if (strlen($ex[1])==2)
{
// true
}
else
{
// false
}
But again, as i've commented already, if you really have floating input, this is just not a reliable way, as floating numbers are without set decimal places, even if they appears so because of the rounding at the float=>string conversion
What you can do, if you really have floating numbers and wish to have xxx.yy format numbers:
1) convert float to string using round($x,2), so it will round to 2 decimal places.
2) explode the number as i've described, and do the following:
while (strlen($ex[1]<2)) {$ex[1].='0';}
$number=implode('.',$ex);
I would use the following function for that:
function isFloatWith2Decimals($number) {
return (bool) preg_match('/^(?:[1-9]{1}\d*|0)\.\d{2}$/', $number);
}
This will also check if you have only one leading 0 so number like 010.23 won't be considered as valid whereas number like 0.23 will.
And if you don't care about leading 0 you could use simpler method:
function isFloatWith2Decimals($number) {
return (bool) preg_match('/^\d+\.\d{2}$/', $number);
}
Of course numbers need to be passed as string - if you pass 100.00 won't be considered as true, whereas '100.00' will

How to delete trailing zeros after the 3rd decimal place in PHP?

thanks in advance.
I have a WP WooCommerce store and need to upload some prices that have 3 decimal places, e.g. £0.012 (products that are purchased in volumes of 000s).
The majority of my products are 'ordinary' with 2 decimal places.
There is a function in WooCommerce that allows for 3 decimal places - fine. Also a function to delete trailing zeros, but it deletes them if it's an integer e.g. £10.00 becomes £10.
My problem arises when the 95% of 'ordinary' price products start showing £10.000 or £5.230.
In a nutshell I'm looking for a way to delete trailing zeros but ONLY after the 3 decimal place;
Retain - £0.012
Delete any 3rd decimal 0 on prices like £10.00 or £5.23
Does anyone have a good solution?
Thanks
If you want to use regular expressions you can match them with
(?<=\d{2})(0+)$
preg_replace("/(?<=\d{2})(0+)$/", "", $price_string)
to match all zeroes which come after at least two digits. (It will match the zeroes in parenthesis):
12.002(0)
12.00(0000)
12.01(000000)
12.232(0)
12.123
an if else statement would probably work, unless you also have prices like 10.001:
$price = '0.001';
if ($price < 1) {
// don't round
} else {
$price = number_format($price, 2);
}
or just
$price = ( $price < 1 ) ? $price : number_format($price, 2) ;
Why not just something like this ↓ ?
$numberAsString = number_format($yourUglyNumber, 2, '.', ' ');
PHP function number_format
If you get the number as string with the money sign, you can first filter this out:
$moneyString = "£300.4578525";
// remove all non-numeric and cast to number
$moneyNum = preg_replace("/[^0-9.]/", "", $moneyString) + 0;
// format
$formatted = number_format($moneyNum, 2, '.', ' ');
// add the money symbol if you want
$formatted = '£' + $formatted.

Advanced Php Number Formatting

I want to have a PHP number formatted with a minimum of 2 decimal places and a maximum of 8 decimal places. How can you do that properly.
Update: I'm sorry, my question is say I have number "4". I wish for it to display as "4.00" and if I have "2.000000001" then it displays as "2.00" or if I have "3.2102" it will display as such. There is a NSNumber formatter on iPhone, what is the equivalent in PHP.
This formats the $n number for 8 decimals, then removes the trailing zero, max 6 times.
$s = number_format($n, 8);
for($i=0; $i<8-2; $i++) {
if (substr($s, -1) == '0')
$s = substr($s, 0, -1);
}
print "Number = $s";
Use sprintf() to format a number to a certain number of decimal places:
$decimal_places = 4;
$format = "%.${decimal_places}f";
$formatted = sprintf($format,$number);
I don't understand why you would want to display numbers to an inconsistent degree of accuracy. I don't understand what pattern you're trying to describe in your comment, either.
But let us suppose that you want the following behaviour: you want to express the number to 8 decimal places, and if there are more than 2 trailing zeroes in the result, you want to remove the excess zeroes. This is not much more difficult to code than it is to express in English. In pseudocode:
$mystring = string representation of number rounded to 8 decimal places;
while (last character of $mystring is a 0) {
chop off last character of $mystring;
}
Check the number format function:
<?php
$num = 43.43343;
$formatted = number_format(round((float) $num, 2), 2);
?>
http://php.net/manual/en/function.number-format.php
Using preg_match just get the zero ending with and then rtim it
<?php
$nn = number_format(10.10100011411100000,13);
preg_match('/[0]+$/',$nn,$number);
if(count($number)>0){
echo rtrim($nn,$number[0]);
}
Hope it will help you.

Categories