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

Reply via email to