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. 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 David