# xor_bits

Definition: | atom x3 = xor_bits(atom x1, atom x2)
Description: | Perform the logical XOR (exclusive OR) operation on corresponding bits in x1 and x2. A bit in x3 will be 1 when one of the two corresponding bits in x1 or x2 is 1, and the other is 0.
pwa/p2js: | Supported.
Comments: | This function may be applied to an atom or sq_xor_bits() to all elements of a sequence. The rules for sequence operations apply. The arguments must be representable as 32-bit numbers, either signed or unsigned. If you intend to manipulate full 32-bit values, you should declare your variables as atom, rather than integer. The integer type is limited to 31-bits. Results are treated as signed numbers. They will be negative when the highest-order bit is 1. Caution: many cryptographic functions and the like require unsigned 32-bit integers, especially when bit-shifting, for which xor_bitsu() can be used instead. See also example 2 below. Unlike and_bits() and or_bits(), there is no infix operator alternative to xor_bits().
Example 1: |
    a = xor_bits(#0110, #1010)
    -- a is #1100
Example 2: | The following discrepancy was noted during the rosettacode PCG32 task:
    atom x = #909E8125,
         l = x << 32,
    --   l = and_bitsu(x << 32,#FFFFFFFF),
         a = xor_bitsu(x,l),
         u = and_bitsu(a,#FFFFFFFF)
    printf(1,"x:%x, l:%x, a:%x (%d)\n",{x,l,a,u})
    -- 32bit: x:909E8125, l:909E812500000000, a:909E8125 (2426306853)
    -- 64bit: x:909E8125, l:909E812500000000, a:80000000909E8125 (0)
    -- as commented out (both): x:909E8125, l:0, a:909E8125 (2426306853)
Technically, of course, you could easily argue that is an outright bug, but to cut a long rant about CPU/FPU/SSE instructions short, it is far easier just to say that sometimes for consistency between 32 and 64 bit you may have to explicitly enforce the 32-bit aspect.
Implementation: | pilx86.e emits inline binary directly for two initialised integers, otherwise a call to :%opXorBits in builtins\VM\pMath.e xor_bitsu() is currently implemented in builtins/ubits.e (also an autoinclude), though that could probably be improved on, if needed.
See Also: | and_bits, or_bits, not_bits, int_to_bits, int_to_bytes