PHP float with 2 decimal places: .00 - php

When I do this typecasting:
(float) '0.00';
I get 0. How do I get 0.00 and still have the data type as a float?

A float doesn't have 0 or 0.00 : those are different string representations of the internal (IEEE754) binary format but the float is the same.
If you want to express your float as "0.00", you need to format it in a string, using number_format :
$numberAsString = number_format($numberAsFloat, 2);

As far as i know there is no solution for PHP to fix this. All other (above and below) answers given in this thread are nonsense.
The number_format function returns a string as result as written in PHP.net's own specification.
Functions like floatval/doubleval do return integers if you give as value 3.00 .
If you do typejuggling then you will get an integer as result.
If you use round() then you will get an integer as result.
The only possible solution that i can think of is using your database for type conversion to float. MySQL for example:
SELECT CAST('3.00' AS DECIMAL) AS realFloatValue;
Execute this using an abstraction layer which returns floats instead of strings and there you go.
JSON output modification
If you are looking for a solution to fix your JSON output to hold 2 decimals then you can probably use post-formatting like in the code below:
// PHP AJAX Controller
// some code here
// transform to json and then convert string to float with 2 decimals
$output = array('x' => 'y', 'price' => '0.00');
$json = json_encode($output);
$json = str_replace('"price":"'.$output['price'].'"', '"price":'.$output['price'].'', $json);
// output to browser / client
print $json;
exit();
Returns to client/browser:
{"x":"y","price":0.00}

0.00 is actually 0. If you need to have the 0.00 when you echo, simply use number_format this way:
number_format($number, 2);

You can show float numbers
with a certain number of decimals
with a certain format (localised)
i.e.
$myNonFormatedFloat = 5678.9
$myGermanNumber = number_format($myNonFormatedFloat, 2, ',', '.'); // -> 5.678,90
$myAngloSaxonianNumber = number_format($myNonFormatedFloat, 2, '.', ','); // -> 5,678.90
Note that, the
1st argument is the float number you would like to format
2nd argument is the number of decimals
3rd argument is the character used to visually separate the decimals
4th argument is the character used to visually separate thousands

Use the number_format() function to change how a number is displayed. It will return a string, the type of the original variable is unaffected.

try this
$nom="5695.5";
number_format((float)($nom), 2, '.', ','); // -> 5,695.50
$nom="5695.5215";
number_format((float)($nom), 2, '.', ','); // -> 5,695.52
$nom="5695.12";
number_format((float)($nom), 0, '.', ','); // -> 5,695
//use round()
$nom="5695.12";
number_format((float)round($nom), 2, '.', ','); // -> 5,695.00
$nom="5695.52";
number_format((float)round($nom), 2, '.', ','); // -> 5,696.00

you can try this,it will work for you
number_format(0.00, 2)

A number of comments on this page have missed the fundamental point that the question is ill-formed. Floating point is a binary representation, designed for efficient calculations; it fundamentally has no notion of decimal digits of any sort.
So asking this:
How do I get "0.00" instead of "0" and still have the data type as a float?
Is like asking this:
How do I get "deux" instead of "zwei" and still have the language as English?
Whether you specify the input as "2", or "2.0", or "2.000000000", if you ask for a floating point value, what will be stored in memory is this (in IEEE 754 double-precision):
0100000000000000000000000000000000000000000000000000000000000000
If you convert to an integer, the value stored in memory is this (assuming a 64-bit system):
0000000000000000000000000000000000000000000000000000000000000010
(Note that "integer" in this context is not just a synonym for "whole number", it is a specific data type, with its own rules for how values should be represented in memory.)
By contrast, the string "2" would look like this:
00110010
And the string "2.00" would look like this:
00110010001011100011000000110000
(In a PHP program, there would actually be additional information in memory, such as an indicator of the type, but that's not really relevant here.)
So, the question can only be answered by rephrasing it as a conversion: given the input of a floating point number, how do I choose a string representation which has a fixed number of decimals.
As others have pointed out, the answer to that is to use number_format.
The question doesn't mention JSON, but several comments do, so I will also point out that PHP's json_encode function has an option JSON_PRESERVE_ZERO_FRACTION, which will format a floating point number that happens to be a whole number with a trailing ".0", for instance:
$example = ['int' => 2, 'float' => 2.0];
echo json_encode($example);
# => {"int":2,"float":2}
echo json_encode($example, JSON_PRESERVE_ZERO_FRACTION);
# => {"int":2,"float":2.0}
Again, note that this is a string representation of the value.

You can use round function
round("10.221",2);
Will return 10.22

You can use floatval()
floatval()

try this
$result = number_format($FloatNumber, 2);

You can use this simple function.
number_format ()
$num = 2214.56;
// default english notation
$english_format = number_format($num);
// 2,215
// French notation
$format_francais = number_format($num, 2, ',', ' ');
// 2 214,56
$num1 = 2234.5688;
// English notation with thousands separator
$english_format_number = number_format($num1,2);
// 2,234.57
// english notation without thousands separator
$english_format_number2 = number_format($num1, 2, '.', '');
// 2234.57

When we format any float value, that means we are changing its data type to string. So when we apply the formatting on any amount/float value then it will set with all possible notations like dot, comma, etc. For example
(float)0.00 => (string)'0.00',
(float)10000.56 => (string) '10,000.56'
(float)5000000.20=> (string) '5,000,000.20'
So, logically it's not possible to keep the float datatype after formatting.

Related

Why PHP round my number when I use json_encode?

I need execute json_encode() and convert my original number from:
50610101800060384093800100001010000000056199999999
to
"50610101800060384093800100001010000000056199999999"
But it return
5.061010180006E+49
I tried this:
ini_set('precision', 30); //With 1, 30, 50, 100, 1000
ini_set('serialize_precision', -1);
'content' => json_encode($params, JSON_NUMERIC_CHECK)
but doesn't work. Can you help me?
50610101800060384093800100001010000000056199999999 exceeds the value of the maximum integer in PHP and so it is promoted to a float and expressed in scientific notation. The float result may be problematic for various reasons as the Manual explains in warning about floating point precision.
If you wish to express the value as if it were an integer you must encapsulate it in a string. That string you may add zero to it but when you do so the result in scientific notation will refer to a float, as follows:
<?php
$s = "50610101800060384093800100001010000000056199999999";
echo $s,"\n";
$x = $s + 0;
echo $x, "\n",is_float($x);
See here.
For more info in re PHP and floats, see here.
On the other hand, if there were an array of numbers whose digits corresponded to the numerical display in the OP's post, you could write code as follows:
<?php
$a = [5,0,6,1,0,1,0,1,8,0,0,0,6,0,3,8,4,0,9,3,8,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,5,6,1,9,9,9,9,9,9,9,9];
foreach($a as $e) {
$e = (string) $e;
}
$foo = join($a);
var_dump($foo);
$foo = bcadd($foo, 1);
var_dump($foo);
See live code.
The reason this example works is because each array value is converted to a numerical string and then the individual elements are joined to form one very long numerical string. BC Math is an extension in PHP which supports arbitrary precision. In this case, the bcadd() function adds one to the numerical string which results in the display of an incremented numerical string value.
Try This [https://3v4l.org/biNJG][1]
If you want this output "50610101800060384093800100001010000000056199999999"
you may want to pass this Value as string after encoding the value to JSON using json_encode
An integer data type is a non-decimal number between -2,147,483,648 and 2,147,483,647.
Rules for integers:
An integer must have at least one digit
An integer must not have a decimal point
An integer can be either positive or negative
Integers can be specified in three formats: decimal (10-based), hexadecimal (16-based - prefixed with 0x) or octal (8-based - prefixed with 0)

PHP lowest common denomination

I am working on a payment gateway and the amount parameter needs to formatted this way:
amount – (digits only) the integer value of the transaction in lowest common denomination (ex. $5.20 is 520)
I have already removed the $ and all values will be rounded to 2 decimal places.
In PHP if i try to cast amount as int ie (int)$amount I am going to loose the .20 in the example though its needed. What could be the best way to go about this?
You can multiply the amount by 100 and then convert it...
$amount = (int)($amount*100);
So 5.20 becomes 520.
If you are not sure about the number of decimal places, you could use regex to strip non-digital values from your string.
echo preg_replace('~\D+~', '', $amount);
\D means any non-numeric character. + means one or more.
If the value needs to be cast as an integer (rather than a string) write(int) just before preg_replace.
Of course, you could use str_replace() and target known characters like: $ and . (and - if it may exist).
After some feedback from the OP...
You can round and format in one step with number_format().
Code: ( Demo: https://3v4l.org/ir54s )
$amounts = array(0.001, 0.005, 5.20, 5.195, 5.204, 5);
foreach ($amounts as $amount) {
echo $amount , "->" , (int)number_format($amount, 2, '', '')."\n";
}
Output:
0.001->0
0.005->1
5.2->520
5.195->520
5.204->520
5->500

Prevent number_format from rounding numbers - add commas and keep the decimal point - PHP

Number format adds the commas I want but removes the decimals.
echo number_format("1000000.25");
This returns 1,000,000
I want it to return 1,000,000.25
I need both the commas and the decimals, without any number rounding. All my values are decimals. They vary in length.
Do I have to use something other than number format?
In case what you meant by they vary in length is related to the decimal part, take a look at this code:
function getLen($var){
$tmp = explode('.', $var);
if(count($tmp)>1){
return strlen($tmp[1]);
}
}
$var = '1000000.255555'; // '1000000.25'; // '1000000';
echo number_format($var, getLen($var));
Some tests
Output for 1000000.255555:
1,000,000.255555
Output for 1000000.25:
1,000,000.25
Output for 1000000:
1,000,000
It counts how many chars there are after the . and uses that as argument in the number_format function;
Otherwise just use a constant number instead of the function call.
And some reference...
From the manual -> number_format():
string number_format ( float $number [, int $decimals = 0 ] )
And you can see in the description that
number
The number being formatted.
decimals
Sets the number of decimal points.
And a bit more:
[...]If two parameters are given, number will be formatted with decimals
decimals with a dot (".") in front, and a comma (",") between every
group of thousands.
$number = '1000000.25';
echo number_format($number, strlen(substr(strrchr($number, "."), 1)));
Explanation:
Number Format takes a second parameter which specifies the number of decimal places required as pointed out in the docs. This Stack overflow answer tells you how to get the number of decimal places of your provided string
The docs for number_format() indicate the second parameter is used to specify decimal:
echo number_format('1000000.25', 2);
Ref: http://php.net/manual/en/function.number-format.php

Number format with a variable decimal place

Is there a built-in/neat way to format a number (just like number_format does), but without any rounding ups/downs?
For instance, number 1234.234 should be formatted as 1,234.234 and another number 1234 should be formatted as 1,234 (i.e. without any trailing .000)
You can define simple custom function for that:
<?php
function custom_number_format($number, $decimal = '.')
{
$broken_number = explode($decimal, $number);
if (isset($broken_number[1]))
return number_format($broken_number[0]) . $decimal . $broken_number[1];
else
return number_format($broken_number[0]);
}
$n1 = '1234.234';
$n2 = '1234';
echo custom_number_format($n1);
echo '<br>';
echo custom_number_format($n2);
?>
Output is:
1,234.234
1,234
Based on the arhey's answer
TLDR ;)
You can use number_format to format the number to a fixed-width format, then use rtrim twice to remove trailing zeroes, and dot.
rtrim(rtrim(number_format($number, 3, '.', ','), '0'), '.')
Starting from the last character, rtrim removes it while it is one of those given. In our case, we remove trailing dots, then we remove an eventual trailing zero.
rtrim(rtrim(number_format(1234.123, 3, '.', ','), '0'), '.')
// returns 1,234.123
rtrim(rtrim(number_format(1234.12, 3, '.', ','), '0'), '.')
// returns 1,234.12 (1,234.120, trimmed to 1234.12)
rtrim(rtrim(number_format(1234, 3, '.', ','), '0'), '.')
// returns 1,234 (1,234.000, trimmed to 1234)
rtrim(rtrim(number_format(1200, 3, '.', ','), '0'),'.')
// returns 1,200 (1,200.000, trimmed to 1200., trimmed to 1200)
Formal form, and discussion about the parameters (notably the decimals count)
rtrim(rtrim(number_format($number, <N>, '<D>', ''), '0'), '<D>')
Where :
D is the decimal separator. To avoid locale-formatting problems, explicitly specify it
N is the maximum digits you number can have.
If you know all your numbers will have less than 3 digits, go and take N=3.
What if you don't know how many decimals are at most ? Well, things are getting more complex.
It may worth recalling (as stated in the PHP documentation) that floats are stored :
with a precision (a number of digits, without distinction whether they are before or after the decimal separator), not a number of decimals
and in their binary form, not their decimal one, and that can lead to rounding errors when reaching precision limit.
For example, floor((0.1+0.7)*10) will usually return 7 instead of the
expected 8, since the internal representation will be something like
7.9999999999999991118....
So there is no universal good value, you'll have to choose it depending on the usual scale of your data.
And that explains why there is no built-in function for that : PHP can't choose for you.
You can use function:
<?php
function getNumberFormat($number) {
$numberAr = explode('.', (string)$number);
$count = 0;
if (2 === count($numberAr)) {
$count = strlen($numberAr[1]);
}
return number_format($number, $count, ',', '.');
}
$test1 = 1234.234;
$test2 = 1234;
echo getNumberFormat($test1); //1,234.234
echo getNumberFormat($test2); //1,234
I really liked arhey's answer, but later realized it has a major flaw. A number like 2100 will get converted to 2,1 instead of 2,100.
Below is how I ended up modifying it.
public function formatDecimal($number)
{
$stringVal = strval($number); //convert number to string
$decPosition = strpos($stringVal, ".");
if ($decPosition !== false) //there is a decimal
{
$decPart = substr($stringVal, $decPosition); //grab only the decimal portion
$result = number_format($stringVal) . rtrim($decPart, ".0");
}
else //no decimal to worry about
{
$result = number_format($stringVal);
}
return $result;
}
It's not as succinct a solution as I was hoping, but in my case I put it into a view helper (I'm using ZF2) and so it's just one simple function call in my view.
Hope this is helpful for someone!
rtrim(number_format(1234.234, 3),'.0');
rtrim(number_format(1234, 3),'.0');
Let's begin with that there's no decimal type in PHP. There's float only.
And if you know how float works, then you know that it's usually not possible to store exact decimal value that you think you have, but it's an approximation. That's because you can't express most of decimal numbers in binary system.
Therefore if you say:
$number = 1234.234;
Then you have a float that is close to this value. The real value is:
1234.23399999999992360244505107402801513671875
Therefore PHP can't just guess how do you want to round it. It needs to be specified explicitly.

PHP String to Float

I am not familiar with PHP at all and had a quick question.
I have 2 variables pricePerUnit and InvoicedUnits. Here's the code that is setting these to values:
$InvoicedUnits = ((string) $InvoiceLineItem->InvoicedUnits);
$pricePerUnit = ((string) $InvoiceLineItem->PricePerUnit);
If I output this, I get the correct values. Lets say 5000 invoiced units and 1.00 for price.
Now, I need to show the total amount spent. When I multiply these two together it doesn't work (as expected, these are strings).
But I have no clue how to parse/cast/convert variables in PHP.
What should I do?
$rootbeer = (float) $InvoicedUnits;
Should do it for you. Check out Type-Juggling. You should also read String conversion to Numbers.
You want the non-locale-aware floatval function:
float floatval ( mixed $var ) - Gets the float value of a string.
Example:
$string = '122.34343The';
$float = floatval($string);
echo $float; // 122.34343
Well, if user write 1,00,000 then floatvar will show error. So -
floatval(preg_replace("/[^-0-9\.]/","",$input));
This is much more reliable.
Usage :
$input = '1,03,24,23,434,500.6798633 this';
echo floatval(preg_replace("/[^-0-9\.]/","",$input));
Dealing with markup in floats is a non trivial task. In the English/American notation you format one thousand plus 46*10-2:
1,000.46
But in Germany you would change comma and point:
1.000,46
This makes it really hard guessing the right number in multi-language applications.
I strongly suggest using Zend_Measure of the Zend Framework for this task. This component will parse the string to a float by the users language.
you can follow this link to know more about How to convert a string/number into number/float/decimal in PHP.
HERE IS WHAT THIS LINK SAYS...
Method 1: Using number_format() Function. The number_format() function is used to convert a string into a number. It returns the formatted number on success otherwise it gives E_WARNING on failure.
$num = "1000.314";
//Convert string in number using
//number_format(), function
echo number_format($num), "\n";
//Convert string in number using
//number_format(), function
echo number_format($num, 2);
Method 2: Using type casting: Typecasting can directly convert a string into a float, double, or integer primitive type. This is the best way to convert a string into a number without any function.
// Number in string format
$num = "1000.314";
// Type cast using int
echo (int)$num, "\n";
// Type cast using float
echo (float)$num, "\n";
// Type cast using double
echo (double)$num;
Method 3: Using intval() and floatval() Function. The intval() and floatval() functions can also be used to convert the string into its corresponding integer and float values respectively.
// Number in string format
$num = "1000.314";
// intval() function to convert
// string into integer
echo intval($num), "\n";
// floatval() function to convert
// string to float
echo floatval($num);
Method 4: By adding 0 or by performing mathematical operations. The string number can also be converted into an integer or float by adding 0 with the string. In PHP, performing mathematical operations, the string is converted to an integer or float implicitly.
// Number into string format
$num = "1000.314";
// Performing mathematical operation
// to implicitly type conversion
echo $num + 0, "\n";
// Performing mathematical operation
// to implicitly type conversion
echo $num + 0.0, "\n";
// Performing mathematical operation
// to implicitly type conversion
echo $num + 0.1;
Use this function to cast a float value from any kind of text style:
function parseFloat($value) {
return floatval(preg_replace('#^([-]*[0-9\.,\' ]+?)((\.|,){1}([0-9-]{1,3}))*$#e', "str_replace(array('.', ',', \"'\", ' '), '', '\\1') . '.\\4'", $value));
}
This solution is not dependant on any locale settings. Thus for user input users can type float values in any way they like. This is really helpful e.g. when you have a project wich is in english only but people all over the world are using it and might not have in mind that the project wants a dot instead of a comma for float values.
You could throw javascript in the mix and fetch the browsers default settings but still many people set these values to english but still typing 1,25 instead of 1.25 (especially but not limited to the translation industry, research and IT)
I was running in to a problem with the standard way to do this:
$string = "one";
$float = (float)$string;
echo $float; : ( Prints 0 )
If there isn't a valid number, the parser shouldn't return a number, it should throw an error. (This is a condition I'm trying to catch in my code, YMMV)
To fix this I have done the following:
$string = "one";
$float = is_numeric($string) ? (float)$string : null;
echo $float; : ( Prints nothing )
Then before further processing the conversion, I can check and return an error if there wasn't a valid parse of the string.
For the sake of completeness, although this question is ancient, it's worth mentioning the filter_var() set of functions, which should not only handle the formatting bits itself, but also validate or sanitise the output, thus being safer to use in the context of a form being filled in by users (or, eventually, a database that might have some corrupted/inconsistent fields):
$InvoicedUnits = (float) filter_var($InvoiceLineItem->InvoicedUnits,
FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
$pricePerUnit = (float) filter_var($InvoiceLineItem->PricePerUnit,
FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
printf("The total is: %.2f\n", $InvoicedUnits * $pricePerUnit); // both are now floats and the result is a float, formatted to two digits after the decimal sign.
This sanitises the output (which will still remain a string) and will accept the current locale's setting of the decimal separator (e.g. dot vs. comma); also, there are more options on the PHP manual for validation (which will automatically convert the result to a float if valid). The results will be slightly different for different scenarios — e.g. if you know in advance that the $InvoiceLineItem will only have valid digits and symbols for floating-point numbers, or if you need to 'clean up' the field first, getting rid of whitespace, stray characters (such as currency symbols!), and so forth.
Finally, if you wish to have nicely-formatted output — since the total is expressed in a currency — you should also take a look at the built-in NumberFormatter class, and do something like:
$InvoicedUnits = (float) filter_var($InvoiceLineItem->InvoicedUnits,
FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
$pricePerUnit = (float) filter_var($InvoiceLineItem->PricePerUnit,
FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION));
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
echo 'Total is: ' . $fmt->formatCurrency($InvoicedUnits * $pricePerUnit, 'EUR') . PHP_EOL;
This will also handle thousand separators (spaces, dots, commas...) according to the configured locale, and other similar fancy things.
Also, if you wish, you can use '' (the empty string) for the default locale string (set either by the server or optionally by the browser) and $fmt->getSymbol(NumberFormatter::INTL_CURRENCY_SYMBOL) to get the default 3-letter currency code (which might not be what you want, since usually prices are given in a specific currency — these functions do not take currency exchange rates into account!).
If you need to handle values that cannot be converted separately, you can use this method:
try {
// use + 0 if you are accounting in cents
$doubleValue = trim($stringThatMightBeNumeric) + 0.0;
} catch (\Throwable $th) {
// bail here if you need to
}

Categories