On Tuesday 17 May 2011 22:06:34 David Harkness wrote: > It appears that PHP is truncating the constant 0x80000000 to be within > MIN_INT and MAX_INT instead of as a bit field, but when shifting 1 << 31 it > doesn't do apply any constraints. That's pretty typical of > bit-manipulation: it will merrily slide 1 bits off either end. This > explains why & produces 0 as it's doing 0x80000000 & 0x7FFFFFFF. It also > explains the second tests.
Yes, that's it! I slightly expanded test output and now it's clear that you are right: $tst1 = (1 << 31); $tst2 = 0x80000000; $tst1_eq = $tst1 & 0x80000000; $tst2_eq = $tst2 & 0x80000000; $str1 = sprintf("%1$032b", $tst1); $str2 = sprintf("%1$032b", $tst2); print "tst1=$tst1 ($str1), tst1_eq=$tst1_eq, tst1_type=".gettype($tst1)."\n"; print "tst2=$tst2 ($str2), tst2_eq=$tst2_eq, tst2_type=".gettype($tst2)."\n"; produces this output: tst1=-2147483648 (10000000000000000000000000000000), tst1_eq=0, tst1_type=integer tst2=2147483647 (01111111111111111111111111111111), tst2_eq=2147483647, tst2_type=integer Now it is obvious to me that PHP 5.2 clamps explicit constants to MAX_INT. Weird, brrrr... > > On 64-bit 5.3.3 I get > > tst1=2147483648, tst1_eq=2147483648, tst1_type=integer > tst2=2147483648, tst2_eq=2147483648, tst2_type=integer > > If I try the 64-bit-equivalent code I get > > tst1=-9223372036854775808, tst1_eq=-9223372036854775808, > tst1_type=integer > tst2=9.22337203685E+18, tst2_eq=-9223372036854775808, tst2_type=double > I get similar results with 5.3 on my amd64 host too. It works as it should, no weirdness. Glad to know that 5.3 get it fixed. Pity to me that I can not update my 5.2 on ARM board. -- Vitalii Demianets -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php