0

I have phantom bug in my code. It appears in one case from 10 attempts. When I try to debug it I found this strange behavior:

$a = floor(1385968017.8665 * 10000); // or (int) (1385968017.8665 * 10000)
// here $a equals to 13859680178664
$b = (1385968017.8665 * 10000);
// here $b equals to 13859680178665

I have such PHP version/configuration:

PHP 5.3.10-1ubuntu3.8 with Suhosin-Patch (cli) (built: Sep  4 2013 20:00:51) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans

UPDATE: I know about floating operations precesion. Same code in C++:

#include <iostream>

int main()
{
    std::cout << std::fixed << (1385968017.8665 * 10000) << std::endl;
    std::cout << (unsigned long long) (1385968017.8665 * 10000) << std::endl;

    return 0;
}

gives me next output:

13859680178664.998047
13859680178664

And it was I expected from it. But why my PHP code shows that (1385968017.8665 * 10000) is precise equals to 13859680178665?

UPDATE 2: As user @core1024 mentioned in comments, PHP possible is rounding result of calculation (1385968017.8665 * 10000). If try php -r 'printf("%f\n",1385968017.8665 * 10000);' result will be somewhere about 13859680178664.998047. Who can explain when and why PHP do this?

Ivan Velichko
  • 6,348
  • 6
  • 44
  • 90

3 Answers3

2

It runs as expected.

You used the FLOOR() function in the first statement, which ROUNDS DOWN a value to the nearest integer.

Check here for more info on that.

As to why it rounds down like that, it's because your value 1385968017.8665 isn't exactly that. Jon Skeet explains that here ..along with Tony the Pony.

Malcolm Salvador
  • 1,476
  • 2
  • 21
  • 40
0

That's because of 1385968017.8665 is an infinite double in binary, and (literal 1385968017.8665) ~= (1385968017.8664998 in computer).

Is round(1385968017.8665 * 10000) what you need?

wumch
  • 1
  • 1
  • Excactly in this case round gives me correct result. But I always want to retrive nearest integer value less or equals to "ideal division result" without floating operations magic. Using round don't save me from phantom bug in my code. – Ivan Velichko Dec 02 '13 at 07:50
0

I found explanation for this problem. My php.ini precision setting is equal to 14. If I increase precision setting by one, this stragne behavior not represented:

$a = floor(1385968017.8665 * 10000); // or (int) (1385968017.8665 * 10000)
// here $a equals to 1385968017866(!)5
Ivan Velichko
  • 6,348
  • 6
  • 44
  • 90