Edit report at https://bugs.php.net/bug.php?id=62240&edit=1

 ID:                 62240
 Updated by:         [email protected]
 Reported by:        zuallauz at gmail dot com
 Summary:            5.4.3 regression, converting from float to int gives
                     incorrect output
 Status:             Not a bug
 Type:               Bug
 Package:            *General Issues
 Operating System:   Ubuntu 12.04 32-bit
 PHP Version:        5.4.3
 Block user comment: N
 Private report:     N

 New Comment:

Well, you weren't rounding. When you do (int)2.9 that's truncation, not 
rounding. So your fix would be to round it. Floating point numbers can't always 
be represented accurately, so you have to account for that in your code. There 
is nothing we can do in PHP to fix this short of not using the built-in 
floating 
point feature, and if we go around that it will be really slow. You can choose 
to do that yourself by using bcmath/gmp yourself if you prefer, of course.

You will find that any other language you try on that machine will give you the 
same "incorrect" result.


Previous Comments:
------------------------------------------------------------------------
[2012-06-08 22:29:34] zuallauz at gmail dot com

I ran that new bit of C code:

First machine (that works properly) came back with:

3.0000000000000000000000000000000000000000000000000000000000000000

Second machine (not working machine) came back with:

2.9999999999999995559107901499373838305473327636718750000000000000

I think we found the problem! In PHP I think I read in the docs that 'When 
converting from float to integer, the number will be rounded towards zero.' so 
that must be why PHP returns a 2 on this machine.

Hmm so what's the best way to fix?

------------------------------------------------------------------------
[2012-06-08 09:54:44] [email protected]

Strange. The PHP log function just looks like this (from ext/standard/math.c):

PHP_FUNCTION(log)
{
        double num, base = 0;

        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|d", &num, 
&base) 
== FAILURE) {
                return;
        }
        if (ZEND_NUM_ARGS() == 1) {
                RETURN_DOUBLE(log(num));
        }
        if (base <= 0.0) {
                php_error_docref(NULL TSRMLS_CC, E_WARNING, "base must be 
greater than 0");
                RETURN_FALSE;
        }
        if (base == 1) {
                RETURN_DOUBLE(php_get_nan());
        } else {
                RETURN_DOUBLE(log(num) / log(base));
        }
}

Since you are calling it as log(8,2) you are hitting the last case there. So 
the 
only code executed is:

RETURN_DOUBLE(log(num) / log(base));

And the RETURN_DOUBLE macro just sets the return value to the double returned 
by 
dividing those two log calls. There should be no difference between the little 
test program and PHP here.

Although..  I think gcc might be playing tricks on us here because I used a 
constant. Try this instead:

#include <stdio.h>
#include <math.h>
int main(char *argv[], int argc) {
        double base = 2.0;
        double num = 8.0;
        printf("%.64f\n",log(num)/log(base));
}

Then compile it using:

gcc a.c -o a -lm

Do you get the same result on both machines?

------------------------------------------------------------------------
[2012-06-08 09:16:26] zuallauz at gmail dot com

Yeah Memtest came back with no errors. The test C program returns the same 
result on both machines. Difference between the machines:

Working machine:
Intel Pentium 4 single core @2Ghz desktop
Ubuntu 10.04 32 bit
glibc 2.11.1
gcc 4.4

Not working machine:
Intel dual core T2300 @1.66Ghz laptop
Ubuntu 12.04 32 bit
glibc 2.15
gcc 4.6

------------------------------------------------------------------------
[2012-06-07 14:08:56] [email protected]

I doubt it is bad memory. What's the difference between the two machines? Same 
architecture? Intel vs. AMD perhaps? Different glibc versions? Different 
compiler 
versions? It would be interesting to know what would cause this on some 
machines 
but not others. What about the little test C program? Does that return the same 
result on both machines?

------------------------------------------------------------------------
[2012-06-07 10:38:18] zuallauz at gmail dot com

Yeah originally I had compiled my own PHP using the flags in the first post. I 
re-downloaded php-5.4.3.tar.bz2 from PHP.net and just did a basic ./configure 
&& make then ran log(8,2) using sapi/cli/php test.php and the output was still 
the same incorrect result:

float(3)
int(2)

However I have just tried the same thing on my other machine running 32bit 
Ubuntu 10.04 with 5.4.3 and it outputs correctly:

float(3)
int(3)

So maybe there's a screw loose/bad memory in the first machine or something. I 
don't have an explanation for it. Probably not a bug after all, sorry!

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=62240


-- 
Edit this bug report at https://bugs.php.net/bug.php?id=62240&edit=1

Reply via email to