This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
Am having an issue where PHP expands the float value e.g. 241.09 becomes 241.0899999999. The issue is, the expanded value is included in a signature, thus the expansion is causing my signature to have a mismatch when matching with the actual data which has the original unexpanded form. How do I prevent the rounding off? My code section is as below:
round(floatval($resultParams["AvailableFunds"]), 2)
Somehow, even after applying the round function, the expansion still occurs. How do I prevent that??
It's caused by the PHP Floating point precision:
Floating point numbers have limited precision.
A solution may be to use only integer, e.g. save the float 123.45 as 12345 and when you need to use display it divide it by 100 and pass it to the number_format function:
$myNumView = number_format($myNum/100, 2, '.', '')+0;
By doing this, number_format returns a string formatted as 1234567.89, then by doing +0 PHP converts it to float (due to the PHP Type Juggling) and removes the rightmost 0 in the decimal part of the number:
$a = '35';
$b = '-34.99';
echo $myNum = ($a + $b);
echo '<br>';
echo $myNumView = number_format($myNum, 4, '.', '')+0;
returns:
0.009999999999998
0.01
And also, why does you get AvailableFunds from a string with floatval? It seems that AvailableFunds is a string containing the amount of fund and other text. I think this is a bad implementation on how saving the fund amount. It's better to save the value as is in a dedicated field as float.
Related
This question already has answers here:
php, var_export fails with float [duplicate]
(1 answer)
Is floating point math broken?
(31 answers)
Float / Float = strange result
(2 answers)
Closed 2 years ago.
Can someone explain what is happening here? I have floating point number that is to be rounded to two decimal points (price).
echo $total . " is rounded to " . round((float)$total,2);
var_export((float)$total);
echo " is rounded to ";
var_export(round((float)$total,2));
echo "\r\n";
Output is:
79.95 is rounded to 79.95
79.9500000000000028421709430404007434844970703125 is rounded to 79.9500000000000028421709430404007434844970703125
So, "echo" rounds to itself. When I use var_export() to output data, seem that round() is not working.
Just for test, I made:
$total = 79.9501234576908988888;
Then I get:
79.950123457691 is rounded to 79.95
79.9501234576908927920158021152019500732421875 is rounded to 79.9500000000000028421709430404007434844970703125
So, "echo" seem to automatically round floats to 11 decimal points. Why round() is not working with var_export is a mystery.
Does anyone have an explanation?
Thanks,
Rudolf
Floating point numbers have specific, limited precision. Although it depends on the system, PHP typically uses the IEEE 754 double precision format, which will give a maximum relative error due to rounding in the order of 1.11e-16.
In your case, if you use var_export, it will output (or return) a parsable string representation of a variable, which in this case will also return all the data when your data is stored as a float variable.
That's why when you execute the following
var_export(round((float)$total,2));
The system will first round up the $total to 79.95, but since you have specified the float cast, it will store it to the system's data precision and so when you use the var_export to faithfully return the data, it will give you something like
79.9500000000000028421709430404007434844970703125
On the other hand, the PHP var_export function is intelligent enough to distinguish the type of data you are trying to parse. (even if you do not use the float cast). Hence if you parse "79", the value will be regarded as an integer, if you parse "79.123", the value will be regarded as float.
Say for the following codes:
<?php
//$total = 79.9501234576908988888;
$total = 79;
echo "parsing 79";
echo "<br>";
var_export((float)$total);
echo " is rounded to ";
var_export(round((float)$total,2));
echo "<br><br>";
$total = 79.123;
echo "parsing 79.123";
echo "<br>";
var_export($total);
echo " is rounded to ";
var_export(round($total,2));
echo "<br><br>";
?>
The result will be :
parsing 79
79 is rounded to 79
parsing 79.123
79.1230000000000046611603465862572193145751953125 is rounded to 79.1200000000000045474735088646411895751953125
How var_export () is rounded depends on the PHP version and the system setting 'serialize_precision'. You can display the setting with:
var_dump(ini_get('serialize_precision'));
If your rights allow you can with
ini_set('serialize_precision',"-1");
change this. "-1" means that an enhanced algorithm for rounding such numbers will be used.
The instruction must always be at the beginning of your script or you can change the setting in your php.ini.
I know the question is very basic but it seems nothing working for me.
I have a number (either or float or integer) which I want to be formatted upto two decimal point. For this purpose I'm using PHP function number_format but it converts my number to string.
To convert it back to float I am using (float) or floatval(). But these functions just truncates the number after converting it to float from string.
Here is my code
$revenue_sum = array_sum(array_column($val2, 'weighted_revenue')); //23722
$test = number_format($revenue_sum, 2); //"23,722.00"
$test = (float)number_format($revenue_sum, 2); //23.0
$test = floatval(number_format($revenue_sum, 2)); //23.0
I want the $test to be 23722.00 for the $revenue_sum = 23722
If $revenue_sum = 2372.2 the $test should be 2372.20
number_format() function can be used as follows:
echo number_format($revenue_sum, 2,'.',''); // will return 23722.00 for the $revenue_sum = 23722
You are trying to type cast with ',' value, it is truncating the string.
you can try this
<?php echo sprintf("%2.2f", 8900.258); ?>
which will output as
8900.26
If you assign a floating point value to a variable, then it is converted to an internal binary format (usually using IEEE 754). Not all possible values has an internal representation. So while scanning a text, the float is rounded to the nearest possible value. So for example 1.23 is rounded to 1.22999999999999998.
Because of the internal representation, there is no difference between 100 or 1e2 or 100.0 or 100.0000.
And when printing a floating point value without any formatting instruction, PHP guess a good format and rounding some digits. So 1.22999999999999 is displayed as 1.23(may varies on different systems).
In general: As long you are calculating, formatting doesn't matter. It is mostly the best, to ignore the decimal fragments on debugging. But when printing (=converting to text), use functions like format_number() or any of the printf() functions.
To be more pragmatic:
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
On My PHP server Float values changes when i print on website in json format.
but working ok on localhost.
Code:
$float = 1.440030394;
$value = round($float,5); // 1.44003
$response = array();
$response['status'] = true;
$response['message'] = "success";
$response['values'] = $value;
echo json_encode($response);
// test if value is really true?
echo "<br>test<br>";
echo $value."-abc"; // Work ok if float convert to string
Localhost Response is ok, but on Live server response is
{
"status": true,
"message": "success",
"values": 1.44035442150000012452200154
}
Test
1.44003-abc
Any solutions? i try functions : round, number_format but not working.
Float uses mantissa and exponent representation to hold a number. That means that not all bits of the value are saved separately, and this results in an impossibility to represent all numbers.
You can see this for more details: How are floating point numbers stored in memory?.
Basically your number cannot be stored in a float, so any operations you do on it will result in a slight error.
You have 2 options here.
First one is that if the error is not too big for you and you can ignore it, you just need to truncate the number on output result.
Second one is to treat the number like a string or save each individual digit inside an array. This is actually what happens when you converted your number to string on your last edit. Your number is not a number any more, but a string and each of its digits are saved individually.
Almost all languages are based on float for numbers with decimals because of their versatility, but floats should not be used for data where each bit is important (like for money). You can open your console in browser (f12 by default and type 0.8 - 0.7) the output will be 0.100000000009 or something like that, because 0.1 doesn't have an exact representation, but the error is small enough to be ignored usually.
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
I have this simple substraction code:
<?php
$n1 = 257931.076;
$n2 = 257930;
echo $n1 - $n2;
?>
Why i got 1.0760000000009 instead of 1.076
Where did the 0000000009 came from? i need precise result and i don't want to use round() or number_format() because sometime i have more than 3 decimal, for example: 12345.678912, anyone know?
I have tried to use round() or number_format() but it only for fixed decimal point, not dynamic
As #GordonM perfectly explained it, you cannot expect exact results when using floating point values.
You can use a library such as brick/math to perform exact calculations on decimal numbers of any size:
use Brick\Math\BigDecimal;
$n1 = BigDecimal::of('257931.076'); // pass the number as a string to retain precision!
$n2 = 257930;
echo $n1->minus($n2); // 1.076
The library uses GMP or BCMath internally when available, but can work without these extensions as well (with a performance penalty).
For technical reasons that every programmer should be aware of, IEEE floating point numbers simply can't represent numbers precisely and will use the closest approximation they can when storing them (In fact the only fractions that can be stored perfectly have denominators that are powers of 2 (1/2, 1/4, 1/8, 1/16, etc. All other values are approximations). PHP has an ini value called "precision", which controls how many digits are considered significant WHEN OUTPUTTING floating point values. It defaults to 14, with any digits after that hidden.
However, the actual value stored may try to approximate the desired value with far more digits than that. If you change precision, you'll see what is really being stored.
php > $test = 0.1;
php > var_dump ($test);
php shell code:1:
double(0.1)
php > ini_set("precision", 100);
php > var_dump ($test);
php shell code:1:
double(0.1000000000000000055511151231257827021181583404541015625)
php > var_dump (0.25);
php shell code:1:
double(0.25)
php > var_dump (0.4);
php shell code:1:
double(0.40000000000000002220446049250313080847263336181640625)
What can you actually do about this? Not a great deal, this is just a consequence of how floating point works. You can try to avoid using floating point if you need exact values (for example when dealing with money amounts, store 3.99 as 399 pennies/cents instead of 3.99 pounds/dollars), or you can use the "bugnum" libraries that are available in PHP, GMP and BC_Math, but these are both tricky to use and have their own sets of gotchas. They can also be hard on storage and/or processor time. In most cases it's best to just live with it and be aware that when you're dealing with floating point you're not dealing with an exact representation.
This question already has answers here:
round in PHP shows scientific notation instead of full number
(3 answers)
Closed 9 years ago.
Why does echo 100000000000000; output 1.0E+14 and not 100000000000000?
This kind of transformation of integers on output happens only for integers that are 15 digits long and longer.
PHP will convert an integer to float if it is bigger than PHP_INT_MAX. For 32-bit systems this is 2147483647.
The answer to the questions is related to the string representation of floats in PHP.
If the exponent in the scientific notation is bigger than 13 or smaller than -4, PHP will use scientific representation when printing floats.
Examples:
echo 0.0001; // 0.0001;
echo 0.00001; // 1.0E-5
// 14 digits
echo 10000000000000; // 10000000000000
// 15 digits
echo 100000000000000; // 1.0E+14
See float vs. double precision
That number is too big to fit into a 32 bit integer so PHP is storing it in a float.
See the integer overflow section in the php manual.
On the off chance that you need really big integers, look into GMP.
PHP cannot handle integers that big, and therefore treats them as floats. Floats are typically represented in scientific notation to take into account the inaccuracies past a certain number of significant digits.
The number is too big to be stored as integer by PHP on your platform,
so it is stored as a floating-point number.
The rules of conversion to string are different for float-numbers and integers.
Try the following:
var_dump(100000000000000);
echo(is_int(100000000000000) ? 'an integer' : 'not an integer');
Output:
float(1.0E+14)
not an integer
Any number larger than PHP's built-in integer size is stored and represented as a float.
To format a number in a particular way on output, use a function such as printf .