问题
Last weekend I changed webhosts for my website. The host server I was on was a 32-bit OS and the one I moved to is 64-bit. Unexpectedly, some of my PHP scripts started giving incorrect results.
In my case the << and >> (bit shift) operations were the culprit. I ended up having to mask the result with 0xFFFFFFFF and then changing the result if negative for it to work as it did before.
Are there any other possible problems in my PHP scripts I should look for?
回答1:
It's a high level language, so anything non-bit related (bitwise operators, bitshift) will be the same.
回答2:
An integer may be 64bit instead of 32bit. There are some bizarre cases where this may cause problems.
回答3:
bit manipulation requires special care to make portable between systems/architectures.
In C, << and >> operations can be made portable by using unsigned variables, which removes the ones/twos compliment rules for negative numbers.
As a general rule, dont use fixed-length masks for bit manipulation (like & and |). These are architecture dependent.
Eg. Resetting the last 4 bits: the mask 0xF0 will work on an 8-bit architecture, but not 16-bit. The results will be different (16-bit may have other bits that are set that are not included in the mask).
To overcome this problem, make use of the ~ operator. The mask ~0xF is equivalent to 0xF0, but will work on any architecture. All bits except the last 4 will be reset
回答4:
strtotime behaves differently on 64 bit. From PHP.net:
Note:
The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.) Additionally, not all platforms support negative timestamps, therefore your date range may be limited to no earlier than the Unix epoch. This means that e.g. dates prior to Jan 1, 1970 will not work on Windows, some Linux distributions, and a few other operating systems. PHP 5.1.0 and newer versions overcome this limitation though.
For 64-bit versions of PHP, the valid range of a timestamp is effectively infinite, as 64 bits can represent approximately 293 billion years in either direction.
We had code that was doing strtotime('0000-00-00') and expected the result to be false, when we moved to 64 bit we got back a negative integer.
回答5:
Only problem's you'll see are when you relied on 32-bit binary representation of data. Mainly because PHP uses signed integers, you'll see issues in Hashing, key generation, etc... when explicitly casting to int with (int), numbers > 2^32 will wrap where as they will not wrap in a 64 bit environment unless they are > 2^64 of course.
4 vs 8 bit example:
Decimal value issues:
0010 >> 1 = 0001 [ 1 dec ]
0000 0010 >> 1 = 0000 0001 [ 1 dec ]
These both produce the same result (decimal wise), however:
0100 << 1 = 1000 [ -8 dec ]
0000 0100 << 1 = 0000 1000 [ 16 dec ]
Wrapping issues:
1000 << 1 = 0000 [ 0 dec ]
0000 1000 << 1 = 0001 0000 [ 32 dec ]
All integer/floating point ops will be treated as 64-bit values, so if your end result relies on 32bit chunks you will have to compensate for such.
回答6:
The results of floating point division will be affected by the increase to 64-bits; so if you have code that does something stupid like comparing the results of floating point division to hardcoded constants, expect it to break.
来源:https://stackoverflow.com/questions/397738/32-to-64-bit-gotchas-in-php