Xor Bytes in Java

17,972

Solution 1

Yes, both statements are equivalent. When working with binary operators in general, including ^, Java applies "binary numeric promotion" to both operands to ensure that they are both at least int values. Section 5.6.2 of the JLS covers this:

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

  • If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

  • Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

  • If either operand is of type double, the other is converted to double.

  • Otherwise, if either operand is of type float, the other is converted to float.

  • Otherwise, if either operand is of type long, the other is converted to long.

  • Otherwise, both operands are converted to type int.

(emphasis mine)

and

Binary numeric promotion is performed on the operands of certain operators:

  • The multiplicative operators *, /, and % (§15.17)

  • The addition and subtraction operators for numeric types + and - (§15.18.2)

  • The numerical comparison operators <, <=, >, and >= (§15.20.1)

  • The numerical equality operators == and != (§15.21.1)

  • The integer bitwise operators &, ^, and | (§15.22.1)

  • In certain cases, the conditional operator ? : (§15.25)

(emphasis mine)

Whether you apply the (int) casts or not, byte1 and byte2 will both be promoted to int before the operation. That is also why the cast back to (byte) is necessary.

Solution 2

What happens is that when the value is cast from byte to int, 24 new bits are inserted in front of the 8 bits of a byte. These bits could be all 0's or all 1's (since byte is a signed type). The result of ^ could therefore have 24 zeroes or 24 ones as the most significant bits. However, when the result is cast back to byte, those 24 bits are thrown away, no matter what they are; and since ^ is done on a bit-by-bit basis, the low-order 8 bits are the same as they would be if there were an ^ operation on bytes--the upper 24 bits don't have any effect on the lower 8.

Share:
17,972
Kent
Author by

Kent

Currently studying software engineering at the University of Ottawa while (Dream_Job == Game_Designer){ striveForSuccess(); }

Updated on June 06, 2022

Comments

  • Kent
    Kent about 2 years

    Java has no support for bit-wise operations on bytes. I would like to xor two bytes like so:

    xoredByte = byte1 ^ byte2;
    

    In java this would have to be done as:

    xoredByte = (byte) (byte1 ^ byte2);
    

    Which compiles to:

    xoredByte = (byte) ((int)byte1 ^ (int)byte2);
    

    Does this work in all cases? What I mean is, are these equivalent statements?

    If not, what would the code be to perform this operation?