Java Tutorial/Operators/Bitwise Operators

Материал из Java эксперт
Перейти к: навигация, поиск

All bitwise operators in action

// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
import java.util.Random;
public class MainClass {
  public static void main(String[] args) {
    Random rand = new Random();
    int i = rand.nextInt();
    int j = rand.nextInt();
    printBinaryInt("-1", -1);
    printBinaryInt("+1", +1);
    int maxpos = 2147483647;
    printBinaryInt("maxpos", maxpos);
    int maxneg = -2147483648;
    printBinaryInt("maxneg", maxneg);
    printBinaryInt("i", i);
    printBinaryInt("~i", ~i);
    printBinaryInt("-i", -i);
    printBinaryInt("j", j);
    printBinaryInt("i & j", i & j);
    printBinaryInt("i | j", i | j);
    printBinaryInt("i ^ j", i ^ j);
    printBinaryInt("i << 5", i << 5);
    printBinaryInt("i >> 5", i >> 5);
    printBinaryInt("(~i) >> 5", (~i) >> 5);
    printBinaryInt("i >>> 5", i >>> 5);
    printBinaryInt("(~i) >>> 5", (~i) >>> 5);
    long l = rand.nextLong();
    long m = rand.nextLong();
    printBinaryLong("-1L", -1L);
    printBinaryLong("+1L", +1L);
    long ll = 9223372036854775807L;
    printBinaryLong("maxpos", ll);
    long lln = -9223372036854775808L;
    printBinaryLong("maxneg", lln);
    printBinaryLong("l", l);
    printBinaryLong("~l", ~l);
    printBinaryLong("-l", -l);
    printBinaryLong("m", m);
    printBinaryLong("l & m", l & m);
    printBinaryLong("l | m", l | m);
    printBinaryLong("l ^ m", l ^ m);
    printBinaryLong("l << 5", l << 5);
    printBinaryLong("l >> 5", l >> 5);
    printBinaryLong("(~l) >> 5", (~l) >> 5);
    printBinaryLong("l >>> 5", l >>> 5);
    printBinaryLong("(~l) >>> 5", (~l) >>> 5);
  }
  static void printBinaryInt(String s, int i) {
    System.out.println(s + ", int: " + i + ", binary: ");
    System.out.print("   ");
    for (int j = 31; j >= 0; j--)
      if (((1 << j) & i) != 0)
        System.out.print("1");
      else
        System.out.print("0");
    System.out.println();
  }
  static void printBinaryLong(String s, long l) {
    System.out.println(s + ", long: " + l + ", binary: ");
    System.out.print("   ");
    for (int i = 63; i >= 0; i--)
      if (((1L << i) & l) != 0)
        System.out.print("1");
      else
        System.out.print("0");
    System.out.println();
  }
}



-1, int: -1, binary: 
   11111111111111111111111111111111
+1, int: 1, binary: 
   00000000000000000000000000000001
maxpos, int: 2147483647, binary: 
   01111111111111111111111111111111
maxneg, int: -2147483648, binary: 
   10000000000000000000000000000000
i, int: 907739811, binary: 
   00110110000110110000001010100011
~i, int: -907739812, binary: 
   11001001111001001111110101011100
-i, int: -907739811, binary: 
   11001001111001001111110101011101
j, int: -1527787021, binary: 
   10100100111011111101000111110011
i & j, int: 604700835, binary: 
   00100100000010110000000010100011
i | j, int: -1224748045, binary: 
   10110110111111111101001111110011
i ^ j, int: -1829448880, binary: 
   10010010111101001101001101010000
i << 5, int: -1017097120, binary: 
   11000011011000000101010001100000
i >> 5, int: 28366869, binary: 
   00000001101100001101100000010101
(~i) >> 5, int: -28366870, binary: 
   11111110010011110010011111101010
i >>> 5, int: 28366869, binary: 
   00000001101100001101100000010101
(~i) >>> 5, int: 105850858, binary: 
   00000110010011110010011111101010
-1L, long: -1, binary: 
   1111111111111111111111111111111111111111111111111111111111111111
+1L, long: 1, binary: 
   0000000000000000000000000000000000000000000000000000000000000001
maxpos, long: 9223372036854775807, binary: 
   0111111111111111111111111111111111111111111111111111111111111111
maxneg, long: -9223372036854775808, binary: 
   1000000000000000000000000000000000000000000000000000000000000000
l, long: 6929873296403828491, binary: 
   0110000000101011110110110000110000001010100111011000111100001011
~l, long: -6929873296403828492, binary: 
   1001111111010100001001001111001111110101011000100111000011110100
-l, long: -6929873296403828491, binary: 
   1001111111010100001001001111001111110101011000100111000011110101
m, long: -352541115944271612, binary: 
   1111101100011011100001011011100100001111011011000000000100000100
l & m, long: 6920767123913179392, binary: 
   0110000000001011100000010000100000001010000011000000000100000000
l | m, long: -343434943453622513, binary: 
   1111101100111011110111111011110100001111111111011000111100001111
l ^ m, long: -7264202067366801905, binary: 
   1001101100110000010111101011010100000101111100011000111000001111
l << 5, long: 395016600407892320, binary: 
   0000010101111011011000011000000101010011101100011110000101100000
l >> 5, long: 216558540512619640, binary: 
   0000001100000001010111101101100001100000010101001110110001111000
(~l) >> 5, long: -216558540512619641, binary: 
   1111110011111110101000010010011110011111101010110001001110000111
l >>> 5, long: 216558540512619640, binary: 
   0000001100000001010111101101100001100000010101001110110001111000
(~l) >>> 5, long: 359902211790803847, binary: 
   0000010011111110101000010010011110011111101010110001001110000111


Bitwise AND (&)

public class Main {
  public static void main(String[] a) {
    System.out.println(9 & 7);
  }
}
//1





Bitwise complement (~): inverts ones and zeros in a number

public class Main {
  public static void main(String[] a) {
    int i = 1;
    System.out.println(i);
    int j = ~i + 1;
    System.out.println(j);
    i = ~j + 1;
    System.out.println(i);
  }
}
/*
1
-1
1
*/





Bitwise Operator Assignments

public class MainClass {
  public static void main(String args[]) {
    int a = 1;
    int b = 2;
    int c = 3;
    a |= 4;
    b >>= 1;
    c <<= 1;
    a ^= c;
    System.out.println("a = " + a);
    System.out.println("b = " + b);
    System.out.println("c = " + c);
  }
}



a = 3
b = 1
c = 6


Bitwise OR (|)

public class Main {
  public static void main(String[] a) {
    System.out.println(19 | 7);
  }
}
//23





Bitwise XOR (^)

public class Main {
  public static void main(String[] a) {
    System.out.println(9 ^ 7);
  }
}
//14





Convert a number to negative and back

public class Main {
  public static void main(String[] a) {
    int i = 1;
    System.out.println(i);
    int j = ~i + 1;
    System.out.println(j);
    i = ~j + 1;
    System.out.println(i);
  }
}
/*
1
-1
1
*/





Converting Between a BitSet and a Byte Array

import java.util.BitSet;
public class Main {
  public static void main(String[] argv) throws Exception {
     System.out.println(fromByteArray(new byte[]{1,2,3}));
  }
  // Returns a bitset containing the values in bytes.
  public static BitSet fromByteArray(byte[] bytes) {
    BitSet bits = new BitSet();
    for (int i = 0; i < bytes.length * 8; i++) {
      if ((bytes[bytes.length - i / 8 - 1] & (1 << (i % 8))) > 0) {
        bits.set(i);
      }
    }
    return bits;
  }
}
//{0, 1, 9, 16}





Demonstrate the bitwise logical operators

public class MainClass {
  public static void main(String args[]) {
    String binary[] = {
      "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
      "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
    };
    int a = 3; // 0 + 2 + 1 or 0011 in binary
    int b = 6; // 4 + 2 + 0 or 0110 in binary
    int c = a | b;
    int d = a & b;
    int e = a ^ b;
    int f = (~a & b) | (a & ~b);
    int g = ~a & 0x0f;
   
    System.out.println("        a = " + binary[a]);
    System.out.println("        b = " + binary[b]);
    System.out.println("      a|b = " + binary[c]);
    System.out.println("      a&b = " + binary[d]);
    System.out.println("      a^b = " + binary[e]);
    System.out.println("~a&b|a&~b = " + binary[f]);
    System.out.println("       ~a = " + binary[g]);
  }
}



a = 0011
b = 0110
a|b = 0111
a&b = 0010
a^b = 0101
~a&b|a&~b = 0101
~a = 1100


Left shift (<<)

public class Main {
  public static void main(String[] a) {
    System.out.println(9 << 7);
  }
}
//1152





Left shifting as a quick way to multiply by 2

public class MainClass {
  public static void main(String args[]) {
    int i;
    int num = 0xFFFFFFE;
   
    for(i=0; i<4; i++) {
      num = num << 1;
      System.out.println(num);
    }
  }
}



536870908
1073741816
2147483632
-32


Operations on bit-mapped fields.

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * Operations on bit-mapped fields.
 *
 * @author Apache Jakarta POI
 * @author Scott Sanders (sanders at apache dot org)
 * @author Marc Johnson (mjohnson at apache dot org)
 * @author Andrew C. Oliver (acoliver at apache dot org)
 * @author Stephen Colebourne
 * @author Pete Gieser
 * @author Gary Gregory
 * @since 2.0
 * @version $Id: BitField.java 437554 2006-08-28 06:21:41Z bayard $
 */
public class BitField {
    
    private final int _mask;
    private final int _shift_count;
    /**
     * Creates a BitField instance.
     *
     * @param mask the mask specifying which bits apply to this
     *  BitField. Bits that are set in this mask are the bits
     *  that this BitField operates on
     */
    public BitField(int mask) {
        _mask = mask;
        int count = 0;
        int bit_pattern = mask;
        if (bit_pattern != 0) {
            while ((bit_pattern & 1) == 0) {
                count++;
                bit_pattern >>= 1;
            }
        }
        _shift_count = count;
    }
    /**
     * Obtains the value for the specified BitField, appropriately
     * shifted right.
     *
     * Many users of a BitField will want to treat the specified
     * bits as an int value, and will not want to be aware that the
     * value is stored as a BitField (and so shifted left so many
     * bits).
     *
     * @see #setValue(int,int)
     * @param holder the int data containing the bits we"re interested
     *  in
     * @return the selected bits, shifted right appropriately
     */
    public int getValue(int holder) {
        return getRawValue(holder) >> _shift_count;
    }
    /**
     * Obtains the value for the specified BitField, appropriately
     * shifted right, as a short.
     *
     * Many users of a BitField will want to treat the specified
     * bits as an int value, and will not want to be aware that the
     * value is stored as a BitField (and so shifted left so many
     * bits).
     *
     * @see #setShortValue(short,short)
     * @param holder the short data containing the bits we"re
     *  interested in
     * @return the selected bits, shifted right appropriately
     */
    public short getShortValue(short holder) {
        return (short) getValue(holder);
    }
    /**
     * Obtains the value for the specified BitField, unshifted.
     *
     * @param holder the int data containing the bits we"re
     *  interested in
     * @return the selected bits
     */
    public int getRawValue(int holder) {
        return holder & _mask;
    }
    /**
     * Obtains the value for the specified BitField, unshifted.
     *
     * @param holder the short data containing the bits we"re
     *  interested in
     * @return the selected bits
     */
    public short getShortRawValue(short holder) {
        return (short) getRawValue(holder);
    }
    /**
     * Returns whether the field is set or not.
     *
     * This is most commonly used for a single-bit field, which is
     * often used to represent a boolean value; the results of using
     * it for a multi-bit field is to determine whether *any* of its
     * bits are set.
     *
     * @param holder the int data containing the bits we"re interested
     *  in
     * @return <code>true</code> if any of the bits are set,
     *  else <code>false</code>
     */
    public boolean isSet(int holder) {
        return (holder & _mask) != 0;
    }
    /**
     * Returns whether all of the bits are set or not.
     *
     * This is a stricter test than {@link #isSet(int)},
     * in that all of the bits in a multi-bit set must be set
     * for this method to return <code>true</code>.
     *
     * @param holder the int data containing the bits we"re
     *  interested in
     * @return <code>true</code> if all of the bits are set,
     *  else <code>false</code>
     */
    public boolean isAllSet(int holder) {
        return (holder & _mask) == _mask;
    }
    /**
     * Replaces the bits with new values.
     *
     * @see #getValue(int)
     * @param holder the int data containing the bits we"re
     *  interested in
     * @param value the new value for the specified bits
     * @return the value of holder with the bits from the value
     *  parameter replacing the old bits
     */
    public int setValue(int holder, int value) {
        return (holder & ~_mask) | ((value << _shift_count) & _mask);
    }
    /**
     * Replaces the bits with new values.
     *
     * @see #getShortValue(short)
     * @param holder the short data containing the bits we"re
     *  interested in
     * @param value the new value for the specified bits
     * @return the value of holder with the bits from the value
     *  parameter replacing the old bits
     */
    public short setShortValue(short holder, short value) {
        return (short) setValue(holder, value);
    }
    /**
     * Clears the bits.
     *
     * @param holder the int data containing the bits we"re
     *  interested in
     * @return the value of holder with the specified bits cleared
     *  (set to <code>0</code>)
     */
    public int clear(int holder) {
        return holder & ~_mask;
    }
    /**
     * Clears the bits.
     *
     * @param holder the short data containing the bits we"re
     *  interested in
     * @return the value of holder with the specified bits cleared
     *  (set to <code>0</code>)
     */
    public short clearShort(short holder) {
        return (short) clear(holder);
    }
    /**
     * Clears the bits.
     *
     * @param holder the byte data containing the bits we"re
     *  interested in
     *
     * @return the value of holder with the specified bits cleared
     *  (set to <code>0</code>)
     */
    public byte clearByte(byte holder) {
        return (byte) clear(holder);
    }
    /**
     * Sets the bits.
     *
     * @param holder the int data containing the bits we"re
     *  interested in
     * @return the value of holder with the specified bits set
     *  to <code>1</code>
     */
    public int set(int holder) {
        return holder | _mask;
    }
    /**
     * Sets the bits.
     *
     * @param holder the short data containing the bits we"re
     *  interested in
     * @return the value of holder with the specified bits set
     *  to <code>1</code>
     */
    public short setShort(short holder) {
        return (short) set(holder);
    }
    /**
     * Sets the bits.
     *
     * @param holder the byte data containing the bits we"re
     *  interested in
     *
     * @return the value of holder with the specified bits set
     *  to <code>1</code>
     */
    public byte setByte(byte holder) {
        return (byte) set(holder);
    }
    /**
     * Sets a boolean BitField.
     *
     * @param holder the int data containing the bits we"re
     *  interested in
     * @param flag indicating whether to set or clear the bits
     * @return the value of holder with the specified bits set or
     *         cleared
     */
    public int setBoolean(int holder, boolean flag) {
        return flag ? set(holder) : clear(holder);
    }
    /**
     * Sets a boolean BitField.
     *
     * @param holder the short data containing the bits we"re
     *  interested in
     * @param flag indicating whether to set or clear the bits
     * @return the value of holder with the specified bits set or
     *  cleared
     */
    public short setShortBoolean(short holder, boolean flag) {
        return flag ? setShort(holder) : clearShort(holder);
    }
    /**
     * Sets a boolean BitField.
     *
     * @param holder the byte data containing the bits we"re
     *  interested in
     * @param flag indicating whether to set or clear the bits
     * @return the value of holder with the specified bits set or
     *  cleared
     */
    public byte setByteBoolean(byte holder, boolean flag) {
        return flag ? setByte(holder) : clearByte(holder);
    }
}





Performing Bitwise Operations on a Bit Vector

import java.util.BitSet;
public class Main {
  public static void main(String[] argv) throws Exception {
    // Create the bitset
    BitSet bits = new BitSet();
    // Set a bit on
    bits.set(2); 
    // Retrieving the value of a bit
    boolean b = bits.get(0); 
    b = bits.get(2); 
    // Clear a bit
    bits.clear(1);
    // Setting a range of bits
    BitSet bits2 = new BitSet();
    bits2.set(1, 4); 
    // And"ing two bitsets
    bits.and(bits2); 
    // Xor"ing two bitsets
    bits.xor(bits2); 
    // Flip all bits in the bitset
    bits.flip(0, bits.length()); 
    // Andnot"ing two bitsets
    bits.andNot(bits2); 
    // Or"ing two bitsets
    bits.or(bits2); 
  }
}





Represents a collection of 64 boolean (on/off) flags.

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.io.Serializable;
/**
 * Represents a collection of 64 boolean (on/off) flags.  Individual flags 
 * are represented by powers of 2.  For example,<br/>
 * Flag 1 = 1<br/>
 * Flag 2 = 2<br/>
 * Flag 3 = 4<br/>
 * Flag 4 = 8<br/><br/>
 * or using shift operator to make numbering easier:<br/>
 * Flag 1 = 1 &lt;&lt; 0<br/>
 * Flag 2 = 1 &lt;&lt; 1<br/>
 * Flag 3 = 1 &lt;&lt; 2<br/>
 * Flag 4 = 1 &lt;&lt; 3<br/>
 * 
 * 
 * There cannot be a flag with a value of 3 because that represents Flag 1 
 * and Flag 2 both being on/true.
 * 
 *
 * @version $Revision: 478334 $ $Date: 2006-11-22 21:31:54 +0000 (Wed, 22 Nov 2006) $
 */
public class Flags implements Serializable {
    /**
     * Represents the current flag state.
     */
    private long flags = 0;
    /**
     * Create a new Flags object.
     */
    public Flags() {
        super();
    }
    /**
     * Initialize a new Flags object with the given flags.
     *
     * @param flags collection of boolean flags to represent.
     */
    public Flags(long flags) {
        super();
        this.flags = flags;
    }
    /**
     * Returns the current flags.
     *
     * @return collection of boolean flags represented.
     */
    public long getFlags() {
        return this.flags;
    }
    /**
     * Tests whether the given flag is on.  If the flag is not a power of 2 
     * (ie. 3) this tests whether the combination of flags is on.
     *
     * @param flag Flag value to check.
     *
     * @return whether the specified flag value is on.
     */
    public boolean isOn(long flag) {
        return (this.flags & flag) > 0;
    }
    /**
     * Tests whether the given flag is off.  If the flag is not a power of 2 
     * (ie. 3) this tests whether the combination of flags is off.
     *
     * @param flag Flag value to check.
     *
     * @return whether the specified flag value is off.
     */
    public boolean isOff(long flag) {
        return (this.flags & flag) == 0;
    }
    /**
     * Turns on the given flag.  If the flag is not a power of 2 (ie. 3) this
     * turns on multiple flags.
     *
     * @param flag Flag value to turn on.
     */
    public void turnOn(long flag) {
        this.flags |= flag;
    }
    /**
     * Turns off the given flag.  If the flag is not a power of 2 (ie. 3) this
     * turns off multiple flags.
     *
     * @param flag Flag value to turn off.
     */
    public void turnOff(long flag) {
        this.flags &= ~flag;
    }
    /**
     * Turn off all flags.
     */
    public void turnOffAll() {
        this.flags = 0;
    }
    
    /**
     * Turn off all flags.  This is a synonym for <code>turnOffAll()</code>.
     * @since Validator 1.1.1
     */
    public void clear() {
        this.flags = 0;
    }
    /**
     * Turn on all 64 flags.
     */
    public void turnOnAll() {
        this.flags = Long.MAX_VALUE;
    }
    /**
     * Clone this Flags object.
     *
     * @return a copy of this object.
     * @see java.lang.Object#clone()
     */
    public Object clone() {
        try {
            return super.clone();
        } catch(CloneNotSupportedException e) {
            throw new RuntimeException("Couldn"t clone Flags object.");
        }
    }
    /**
     * Tests if two Flags objects are in the same state.
     * @param obj object being tested
     * @see java.lang.Object#equals(java.lang.Object)
     *
     * @return whether the objects are equal.
     */
    public boolean equals(Object obj) {
        if (!(obj instanceof Flags)) {
            return false;
        }
        if (obj == this) {
            return true;
        }
        Flags f = (Flags) obj;
        return this.flags == f.flags;
    }
    /**
     * The hash code is based on the current state of the flags.
     * @see java.lang.Object#hashCode()
     *
     * @return the hash code for this object.
     */
    public int hashCode() {
        return (int) this.flags;
    }
    /**
     * Returns a 64 length String with the first flag on the right and the 
     * 64th flag on the left.  A 1 indicates the flag is on, a 0 means it"s 
     * off.
     *
     * @return string representation of this object.
     */
    public String toString() {
        StringBuffer bin = new StringBuffer(Long.toBinaryString(this.flags));
        for (int i = 64 - bin.length(); i > 0; i--) {
            bin.insert(0, "0");
        }
        return bin.toString();
    }
}





Returns a byte array of at least length 1

import java.util.BitSet;
public class Main {
  public static void main(String[] argv) throws Exception {
    BitSet bitset = new BitSet();
    bitset.set(1);
    System.out.println(toByteArray(bitset));
  }
  public static byte[] toByteArray(BitSet bits) {
    byte[] bytes = new byte[bits.length() / 8 + 1];
    for (int i = 0; i < bits.length(); i++) {
      if (bits.get(i)) {
        bytes[bytes.length - i / 8 - 1] |= 1 << (i % 8);
      }
    }
    return bytes;
  }
}





Signed shift to the right

public class Main {
  public static void main(String[] argv) throws Exception {
    byte b = 11;
    System.out.println(b >> 1); 
  }
}





The Bitwise Logical Operators

A    B    A | B        A & B         A ^ B         ~A
0    0    0            0             0             1
1    0    1            0             1             0
0    1    1            0             1             1
1    1    1            1             0             0
The Bitwise NOT
      00101010   42
     becomes
      11010101

The Bitwise AND
    00101010        42
  & 00001111        15
   __________
    00001010        10
The Bitwise OR
     00101010        42
   | 00001111        15
    _________
     00101111        47
The Bitwise XOR
   00101010        42
 ^ 00001111        15
   _________
   00100101        37





The Bitwise Operators can be applied to the integer types, long, int, short, char, and byte.

OperatorResult~Bitwise unary NOT&Bitwise AND|Bitwise OR^Bitwise exclusive OR>>Shift right>>>Shift right zero fill<<Shift left&=Bitwise AND assignment|=Bitwise OR assignment^=Bitwise exclusive OR assignment>>Shift right assignment>>>=Shift right zero fill assignment<<=Shift left assignment


The Left Shift

// Left shifting a byte value.
public class MainClass {
  public static void main(String args[]) {
    byte a = 64, b;
    int i;
   
    i = a << 2;
    b = (byte) (a << 2);
   
    System.out.println("Original value of a: " + a);
    System.out.println("i and b: " + i + " " + b);
  }
}



Original value of a: 64
i and b: 256 0


The Right Shift

public class MainClass {
  public static void main(String args[]) {
    int a = 32;
    a = a >> 2; // a now contains 8
    System.out.println(a);
  }
}





The Unsigned Right Shift

public class MainClass {
  public static void main(String args[]) {
    int a = -1;
    a = a >>> 24;
    System.out.println(a);
  }
}



255


Unsigned shifting a byte value.

public class MainClass {
  static public void main(String args[]) {
    char hex[] = {
      "0", "1", "2", "3", "4", "5", "6", "7",
      "8", "9", "a", "b", "c", "d", "e", "f"
    };
    byte b = (byte) 0xf1;
    byte c = (byte) (b >> 4);
    byte d = (byte) (b >>> 4);
    byte e = (byte) ((b & 0xff) >> 4);
    System.out.println("              b = 0x"
      + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);
    System.out.println("         b >> 4 = 0x"
      + hex[(c >> 4) & 0x0f] + hex[c & 0x0f]);
    System.out.println("        b >>> 4 = 0x"
      + hex[(d >> 4) & 0x0f] + hex[d & 0x0f]);
    System.out.println("(b & 0xff) >> 4 = 0x"
      + hex[(e >> 4) & 0x0f] + hex[e & 0x0f]);
  }
}



b = 0xf1
b >> 4 = 0xff
b >>> 4 = 0xff
(b & 0xff) >> 4 = 0x0f


Use bitwise operator to create hash code

public class Main {
  int instanceField;
  {
    int hc = hashCode();
    instanceField = hc;
    for (int i = 0; i < 32; i++) {
      System.out.print((hc & 0x80000000) != 0 ? "1" : "0");
      hc <<= 1;
    }
  }
  public static void main(String[] args) {
    System.out.println(new Main().instanceField);
    System.out.println(new Main().instanceField);
  }
}