From:             swoo at gvlabs dot com
Operating system: winxp
PHP version:      5.0.2
PHP Bug Type:     Variables related
Bug description:  discrepancy of bitwise operations between php4.3.9 and 
php5.0.2

Description:
------------
This problem was discovered when I was testing some working code in
preparation for migrating from php4 to php5.
The example is a fragment of the logic used to read an ieee 754 number
from an excel spreadsheet. When you run the code in php4 it yields the
correct interpretation.  However, with php5 it appears that the bitwise
mask and shift when setting $fexp fails with the code that works with
php4.
Also, the php5 resolution of the number is slightly higher.
I recoded the example with the logic that works with php5.
Was there a change in the ieee library or a change to the casting of a
floating point number for bit manipulation in php5? I have not tested this
on any other platform.



Reproduce code:
---------------
<?php  // example of the problem - run with php4 then run with php5

        //25f2d18aa9d26dc0
        $binarydata = pack("CCCCCCCC", 0x25, 0xf2, 0xd1, 0x8a, 0xa9, 0xd2, 0x6d,
0xc0);
        
        // php5 ans: -238.598699007
        // php4 ans: -238.583196077
        
        echo ieee($binarydata, false);
        echo "\n";
        echo ieee($binarydata, true);

function ieee($ieee, $php4test){
        
        if($php4test){
                echo "php4 test ";
        } else {
                echo "php5 test ";
        }
        
        if($php4test){  
        
                // php 4.3.9 Built: Sep 21 2004 14:04:26
                // Zend Engine v1.3.0
                
                $num_lo =
16777216*ord($ieee[3])+(ord($ieee[0])|(ord($ieee[1])<<8)|(ord($ieee[2])<<16));
                $num_hi =
16777216*ord($ieee[7])+(ord($ieee[4])|(ord($ieee[5])<<8)|(ord($ieee[6])<<16));
        
                $fexp = (($num_hi & 0x7ff00000) >> 20) - 1023;   // FAILS IN 
PHP5
                $val = 1+(($num_hi & 0x000fffff)+$num_lo/4294967296)/1048576;
        
        } else {
        
                // php 5.0.2 (cli) build: Sep 24 2004 01:25:41
                // Zend Engine v2.0.2
        
                $num_lo =
(pow(2,24)*ord($ieee[3]))+(ord($ieee[0])|(ord($ieee[1])<<8)|(ord($ieee[2])<<16));
                $num_hi = (pow(2,24)*ord($ieee[7]) &
0x7f)+(ord($ieee[4])|(ord($ieee[5])<<8)|((ord($ieee[6]) & 0x1f)<<16));
        
                $b1 = (ord($ieee[7]) & 0x7f);  // strip the sign bit from the 
high byte
                $b2 = (ord($ieee[6]) >> 4);  // get byte leftmost bits 
                $b3 =($b1 << 4) + ($b2);  // shift 4 bits and add low 4 bits
                $fexp = $b3  - 1023;  // exponent
                $val = 1+ ($num_hi + ($num_lo/pow(2,32)))/pow(2,20);

        }

        if( ($fexp==1024) || ($fexp==-1023) )
                return (float)0;

        if( $fexp > 0 ) {
                for( $i=0; $i<$fexp; $i++ )
                        $val *= 2;
        } else {
                for( $i=0; $i<abs($fexp); $i++ )
                        $val /= 2;
        }
        
        if($php4test){
                if( $num_hi & 0x80000000 ) $val = -$val;
        } else {
                if(ord($ieee[7]) & 0x80) $val = -$val;  // check the high 
byte's high
bit
        }       

        return (float)$val;
}

?>

Expected result:
----------------
(when run with php4)
php5 test -238.583196077
php4 test -238.583196077

(when run with php5)
php5 test -238.598699007
php4 test -238.598699007

Actual result:
--------------
(when run with php4)
php5 test -238.583196077
php4 test -238.583196077

(when run with php5)
php5 test -238.598699007
php4 test 0

-- 
Edit bug report at http://bugs.php.net/?id=30810&edit=1
-- 
Try a CVS snapshot (php4):   http://bugs.php.net/fix.php?id=30810&r=trysnapshot4
Try a CVS snapshot (php5.0): 
http://bugs.php.net/fix.php?id=30810&r=trysnapshot50
Try a CVS snapshot (php5.1): 
http://bugs.php.net/fix.php?id=30810&r=trysnapshot51
Fixed in CVS:                http://bugs.php.net/fix.php?id=30810&r=fixedcvs
Fixed in release:            http://bugs.php.net/fix.php?id=30810&r=alreadyfixed
Need backtrace:              http://bugs.php.net/fix.php?id=30810&r=needtrace
Need Reproduce Script:       http://bugs.php.net/fix.php?id=30810&r=needscript
Try newer version:           http://bugs.php.net/fix.php?id=30810&r=oldversion
Not developer issue:         http://bugs.php.net/fix.php?id=30810&r=support
Expected behavior:           http://bugs.php.net/fix.php?id=30810&r=notwrong
Not enough info:             
http://bugs.php.net/fix.php?id=30810&r=notenoughinfo
Submitted twice:             
http://bugs.php.net/fix.php?id=30810&r=submittedtwice
register_globals:            http://bugs.php.net/fix.php?id=30810&r=globals
PHP 3 support discontinued:  http://bugs.php.net/fix.php?id=30810&r=php3
Daylight Savings:            http://bugs.php.net/fix.php?id=30810&r=dst
IIS Stability:               http://bugs.php.net/fix.php?id=30810&r=isapi
Install GNU Sed:             http://bugs.php.net/fix.php?id=30810&r=gnused
Floating point limitations:  http://bugs.php.net/fix.php?id=30810&r=float
MySQL Configuration Error:   http://bugs.php.net/fix.php?id=30810&r=mysqlcfg

Reply via email to