Integer conversion into account rounding 0.1 [duplicate]

3

echo (int) ((0.1 + 0.7) * 10 )

By logic this should not return 8? 0.1 + 0.7 = 0.8 * 10 = 8

I'm returning 7. why?

    
asked by anonymous 15.05.2017 / 16:23

3 answers

3

By default, PHP uses numbers from floating point , in which case you can get the correct value through rounding, using round or use another type such as float , double .

echo (int) round((0.1 + 0.7) * 10);

It turns out that 0.1 + 0.7 is not exactly 0.8 but 7.99999 ... And the moment it is converted to int the result generated is 7

    
15.05.2017 / 16:51
2

Floating-point math does not work perfectly as expected, look:

console.log(0.1 + 0.7)

If you run this snippet, the result will be 0.799999 ....

Converting this number to integer causes the rounding down:

console.log(parseInt(0.1 + 0.7))

This other snippet shows simply 0. Because 0.79999 rounded down is 0.

However, you multiplied by 10 before converting to integer, that rounded 7.99999 ... down, which is 7.

If you want to know a little more about this strange behavior, you can take a look at on this excellent SO response in English, or on another link. (I will look for links in Portuguese to post here.)

PS: I know his question is in PHP, but I believe that this behavior is common to Javascript too, so set an example, correct me if they are different or if I am wrong

    
15.05.2017 / 16:46
1

I think this question is duplicate this , which in itself is also duplicated from others, but the fact that the representation is 8 , even in float, can fool.

When you give one:

echo ((0.1 + 0.7) * 10);

You get 8 , but if you do this:

if(((0.1 + 0.7) * 10) === 8e0){
    echo 'Este valor é 8';
}

You will see that this value is a lie, it is not the if that is wrong, you can even try using == 8 , the problem is that the calculation itself does not result in 8.

If you run:

var_export(((0.1 + 0.7) * 10));

You will see its true value, 7.999999999999999 , which is different from eight.

For this reason do this:

echo (int)7.999999999999999

It will result in 7 , as it is "equivalent" to making a floor(7.999999999999999) .

This is explained, even with the same values in the documentation and also this answer .

One solution to the problem is to use BCMath or GMP.

bcscale(2);

echo bcmul(bcadd('0.1', '0.7'), '10');

The bcadd will add 0.1 to 0.7 and bcmul will multiply the result of bcadd ( 0.8 ) to 10 .

    
15.05.2017 / 16:53