Hi internals, I tried to fix http://bugs.php.net/bug.php?id=38770. The pack and unpack function returns different values on different platform for options like "N".
Example: print_r(unpack("N", pack("N", -3000))); prints -3000 und x86 and 4294937296 on x86_64. That happens because all the 32 bit integers are handled as long in the zend engine, but long differs from platform (8byte on x86_64 and 4byte on x86). If we pack e.g. a integer to big endian and unpack it to little endian, the long value will be filled by the complete 4byte integer value, so negative values are keeped. But on x86_64 (little endian) only the lower 4byte are set to the integer value while the highter 4bytes are set to zero. Thats why the long values that holds the negative integer value is treaten like a positive long. Thats why I added a few lines to the pack.c to detect if I get a negative integer (e.g. highest bit is set on little endian machines). For a negative integer I fill the higher 4bytes with 1, so that the long value is treaten as negative. You may ask why I take a 4byte _unsigned_ 32bit int from pack and test if the highest bit is set to "cast" it to an signed integer? Thats exactly what php does on x86 machines as it uses signed long internal. here is the patch (against 5.2.0 release): http://sqlbackup.net/data/pack.c.diff I tested it on x86_64 and x86 linux for various pack options. It#s not the best way, the best way might be to cast the signed integers to unsigned in the pack command not in the unpack, but that might be a BC. What do you think? Greets David -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php