This question already has an answer here:
The accuracy of PHP float calculate
(1 answer)
Closed 9 years ago.
<?php
echo (int) ((0.1 + 0.7) * 10);
Why does this output 7 instead of expected 8 ?
From the PHP manual:
... This can lead to confusing results: 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....
It's much recommended to use the bcmath functions if you want accuracy.
As said in the comments. 0.1 + 0.7 is not actually 0.8 it is stored as something like 0.79999999. When you cast it to an int, it will truncate the decimal and just output 7. If you don't cast it to an int it wont truncate and output the expected value.
echo (0.1 + 0.7);
echo ((0.1 + 0.7) * 10);
echo (int) ((0.1 + 0.7) * 10);
Output:
0.8
8
7
Note the very large warning on floating point numbers in the PHP Guide. It pretty much is the exact example you are asking about.
To get past the int truncation problem, use round(), with specified precision
echo round(0.09+0.7,1)*10;
8
This will give you an integer, unlike just omitting the round() or int() in the case of
echo (0.09+0.7)*10;
7.9
Related
This question already has answers here:
Delete digits after two decimal points, without rounding the value
(15 answers)
Closed 3 years ago.
I'm trying to show one decimal place for rating number I have
but it returns unexpected value.
I used number_format and the round functions and both have the same issue, or i'm doing something wrong.
I tried to make this number show one decimal number
4.96 and it always returns 5 instead of 4.9
number_format(4.96, 1)
round(4.96, 1)
round(4.96, 1,PHP_ROUND_HALF_DOWN)
both functions returns 5 instead of 4.9
I searched all answers but couldn't find anything helpful.
Rounding 4.96 will round .9 up, so it will be 5 in all cases. If you want to do it without rounding, you may have to tweak it a bit to fool it:
floor(4.96 * 10) / 10; // 4.9
Here's a function you can use to achieve this.
function convertToSingleDecimal($num, $precision = 2) {
return floor($num) . substr(str_replace(floor($num), '', $num), 0, $precision + 1);
}
print convertToSingleDecimal("4.96", 1);
This question already has answers here:
Why are floating point numbers printed so differently?
(5 answers)
Is floating point math broken?
(31 answers)
Closed 4 years ago.
I have a situation where I cast a double variable to integer. and its giving me wrong result. Why is this happening?
>>> $amount = (double) 1052.10
=> 1052.1
>>> $amount = $amount * 100;
=> 105210.0
>>> (int) $amount;
=> 105209 // weird
I am able to fix it by rounding the variable first ( ie: (int) round($amount)),
But still, I wonder why is this happening?
using PHP 7.2.9
The 'warning' section here states:
Additionally, rational numbers that are exactly representable as floating point numbers in base 10, like 0.1 or 0.7, do not have an exact representation as floating point numbers in base 2, which is used internally, no matter the size of the mantissa. Hence, they cannot be converted into their internal binary counterparts without a small loss of precision.
This question already has answers here:
int((0.1+0.7)*10) = 7 in several languages. How to prevent this?
(7 answers)
Closed 9 years ago.
Me and my colleges were discussing the following problem, and although we came up with some theories we are still seeing it very odd...
<?php
echo (int) ((0.1 + 0.7) * 10);
?>
outputs 7
whilst
<?php
echo (int) (0.1 + 0.7) * 10;
?>
outputs 8 (as expected and as would output if you do it with a calculator)
Could the (int) be causing the issue here? Anyone have an idea?
Thanks a lot and Good Day!
The cast to integer (and related rounding error) occurs at a different point in the formula
Calculate 0.1 plus 0.7, multiply by 10 and cast to integer;
with the expected rounding error, should result in 7
against
Calculate 0.1 plus 0.7, cast to integer, and multiply by 10
casting 0.1 + 0.7 (ie 0.8) to integer should give 0, which multiplied by 10 is still 0
This question already has an answer here:
explain php output
(1 answer)
Closed 9 years ago.
I am trying to understand converting from a float to an int in PHP ,and came across the following code:
echo (int) ( (0.1+0.7) * 10 ); // echoes 7!
My question is why does it echo 7 instead of 8? What is the logic behind it?
Here:
$var = (int) $othervar;
I would guess:
$var = int($othervar);
would work too. BUT IT DOES NOT!
gettype() will tell you the type, get_class() will tell you the class of an object, both return strings, get_class() returns the current class if no argument or null is provided, if you provide a non-object to get_class() it's some sort of error.
These functions are an example of how bad php, gettype() and get_class(), fun fact, because you have to play "guess which has an underscore" you also have is_a() (function, expects $var and "typename") and instanceof (operator).
Instead it is:
$var = intval($othervar);
and there's floatval, the whole lot have val after them! More PHP sillyness.
Note that:
$var = (string) $othervar;
invokes $othervar's __toString() method, but there isn't a __toInt() method, just strings.
Hope this helps.
Addendum:
Integers are always truncated, hence 7.
Other addendum:
If you want more controlled conversion you can use round() which works as one would expect, floor() (rounds down, so 7 less x less 8 floors to 7, -3 less x less-2 floors to -3) and ceil() which rounds up (7 less x less 8 ceils to 8, -3 less x less -2 ceils to -2)
This question is an almost exact copy of:
Why would on earth PHP convert the result of (int) ((0.1+0.7)*10) to 7, not 8?
Even the example!
Because the actual value stored in memory is something like 7.999999999999999999999999 which is caused by rounding error.
you can also use intval()
$float = 7.99999999999999999999999999999999;
$int = intval($float);
echo $int;
This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 3 years ago.
I have a simple comparison in my code:
[simplified]
if (1.7 >= 17 * 0.1) {
echo '1.7 is greater than or equal to ' . 17 * 0.1;
} else {
echo '1.7 is NOT greater than or equal to ' . 17 * 0.1;
}
It gives the result:
1.7 is NOT greater than or equal to 1.7
I wonder can anybody explain this?
This is because native operator are indeed interpreted in base 2, and most base 10 decimal converts badly in base 2.
If you need precision, you need to either only manipulate integers (converts perfectly to base 2) or use a dedicated lib such as bcmath (I wrote a wrapper to ease bcmath usage Math)