How does the floor() function work? [duplicate]

What will be the result of running the following code snippet:

<?
echo floor((0.1+0.7)*10);
?>

And why?


Answer 1, authority 100%

It will be exactly 7. Because (0.1 + 0.7) * 10 will not be 8, but will be 7.99 (any numbers will follow here). And since this number will be less than 8, the result will be 7. Why? features of addition of real numbers.

update for @AlexWindHopeand all others who blamed me in ignorance of mathematics

Read IEEE 754at your leisure and understand that fractional numbers may not always be represented exactly.
Here http://www.h-schmidt.net/FloatApplet/IEEE754.html there is a nice applet that shows exactly what a number looks like inside, in memory. In particular:

0.1 = 0.1000000014 9011612
0.2 = 0.2000000029 8023224
0.7 = 0.6999999880 7907100

Summing everything neatly we have

0.1 + 0.7 = 0.79999998966918712
0.2 + 0.7 = 0.89999999105930324

That is, we see, although the numbers are close to the desired ones, but still not equal to them. I really didn’t find how the floor function was implemented in PHP, I think it would clarify why the first one didn’t have enough, and the second one already had enough to go through the discharge.

Never confuse school math with processor math.

one more update:

If you go to the php site and read what they write about the type float, then just there they give an example given by the questioners :). For all beginners, read until you fully understand.


Answer 2, authority 40%

It’s really a problem of adding real numbers, but I still don’t understand why then floor works with 0.7+0.2, for example, it should output 8…

Well, actually, it’s not the point, in order for it to work and there were no such miracles, you need to write like this:


                   echo floor(round(0.7+0.1, 1)*10); // -> 8

PS: see examples in comments here

UPD
As far as I understand, everything is much more complicated here … And it seems to me that this is a “flat place” for the implementation of the floorfunction, so as not to be unfounded and certainly destroy what @KoVadimhere are some examples:

floor((0.0+0.1)*10); // -> 1
floor((0.1+0.1)*10); // -> 2
floor((0.2+0.1)*10); // -> 3
floor((0.3+0.1)*10); // -> 4
floor((0.4+0.1)*10); // -> 5
floor((0.5+0.1)*10); // -> 6
floor((0.6+0.1)*10); // -> 7
floor((0.7+0.1)*10); // -> 7
floor((0.8+0.1)*10); // -> 9

@KoVadim– yes, you are right, tested for 4.0 – fail 🙂
But in this case round($num, 1)solves this problem

PS: round(), in this case, I used it to solve a specific problem


Answer 3

Round down

0.1+0.7 = 0,8*10 = 8.

A floor(8) = 8


Answer 4

Well, what is not clear here? The language does not use decimals, but “binary” fractions. Now, if you replace 0.1 with 3/32 or 25/256, and replace 0.7 with something like that, the result will be completely predictable.