ID: 30263 Comment by: php at botimer dot net Reported By: tomas_matousek at hotmail dot com Status: Open Bug Type: Variables related Operating System: WinXP PHP Version: 5.0.2 New Comment:
Tomas, I'm not ready to say that the XOR operator is bugged. I will say that the AND and XOR definitely behave differently than OR. All three of these operators pad the shorter string ``on the right'', making the bits more significant. The difference between your expected and actual is due to taking only the overlap and shifting it right by the number of pad bits (bytes/characters, dealing with strings). I've broken your examples down into full binary form, separated the nibbles, and blocked the words. In the AND and XOR, the high word is taken as the result, while the padded section is discarded. I've also included a little c program and its results to give the breakdown. The a variable is padded left, b is padded right. You can see that the results PHP is giving you are the shifted values listed last. As for reasoning for the shift, while the OR is allowed to ``make bits'', I would say that it is for masking purposes, but I can't say exactly what. I'm sure some guru would be more than happy to chime in. I know this is probably a more mathematical treatment than necessary. Simply put, the strings are truncated right of the overlap for AND and XOR, but not for OR. I don't consider it a bug, but can't give the deliberate intention. 00 00 01 02 -> 0000 0000 0000 0000 0000 0001 0000 0010 = 258 01 02 00 00 -> 0000 0001 0000 0010 0000 0000 0000 0000 = 16908288 01 00 01 02 -> 0000 0011 0000 0001 0000 0000 0000 0001 = 16777474 10 20 10 00 -> 0000 0000 0001 0000 0010 0000 0001 0000 = 270536704 00 00 00 01 -> 0000 0001 0000 0000 0000 0000 0000 0000 = 1 -- 01 02 00 00 -> [0000 0001 0000 0010] [0000 0000 0000 0000] 01 00 01 02 -> [0000 0001 0000 0000] [0000 0001 0000 0010] & [0000 0001 0000 0000] [0000 0000 0000 0000] = 256 = 0100 01 02 00 00 -> [0000 0001 0000 0010] [0000 0000 0000 0000] 10 20 10 00 -> [0001 0000 0010 0000] [0001 0000 0000 0000] | [0001 0001 0010 0010] [0001 0000 0000 0000] = 287444992 = 11221000 01 02 00 00 -> [0000 0001 0000 0010] [0000 0000 0000 0000] 00 00 00 01 -> [0000 0000 0000 0000] [0000 0000 0000 0001] ^ [0000 0001 0000 0010] [0000 0000 0000 0001] = 258 = 0102 =====<%======<%===== #include <stdio.h> int main() { unsigned long a = 258; unsigned long b = 16908288; unsigned long c = 16777474; unsigned long d = 270536704; unsigned long e = 1; printf("a & c: %d\n", a & c); printf("a | d: %d\n", a | d); printf("a ^ e: %d\n", a ^ e); printf("----\n"); printf("b & c: %d\n", b & c); printf("b | d: %d\n", b | d); printf("b ^ e: %d\n", b ^ e); printf("(b & c) >> 16: %d\n", (b & c) >> 16); printf("(b ^ e) >> 16: %d\n", (b ^ e) >> 16); return 0; } =====<%======<%===== a & c: 258 a | d: 270536962 a ^ e: 259 ---- b & c: 16777216 b | d: 287444992 b ^ e: 16908289 (b & c) >> 16: 256 (b ^ e) >> 16: 258 Thanks, -Noah Previous Comments: ------------------------------------------------------------------------ [2004-09-28 16:13:52] tomas_matousek at hotmail dot com Description: ------------ If a biwise operator is applied on strings with different lengths one would expect that all such operators would return a string which length is a maximum of the lengths of the operands. Or at least that OR and XOR would do that. But neither is true since OR returns string having the maximum of both lengths and AND, XOR the minimum. That's why I think there is a bug in ^ operator. & operator may behave in both ways, although I would prefer the same behavior as in the case of | and ^. Reproduce code: --------------- echo bin2hex("\x01\x02" & "\x01\x00\x01\x02"),"\n"; echo bin2hex("\x01\x02" | "\x10\x20\x10\x00"),"\n"; echo bin2hex("\x01\x02" ^ "\x00\x00\x00\x01"),"\n"; Expected result: ---------------- 01000000 11221000 01020001 -- or -- 0100 11221000 01020001 Actual result: -------------- 0100 11221000 0102 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=30263&edit=1