Java Tutorial/Operators/Bitwise Operators

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

All bitwise operators in action

   <source lang="java">

// 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();
 }

}</source>



-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 (&)

   <source lang="java">

public class Main {

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

} //1</source>





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

   <source lang="java">

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

  • /</source>





Bitwise Operator Assignments

   <source lang="java">

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);
 }

}</source>



a = 3
b = 1
c = 6


Bitwise OR (|)

   <source lang="java">

public class Main {

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

} //23</source>





Bitwise XOR (^)

   <source lang="java">

public class Main {

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

} //14</source>





Convert a number to negative and back

   <source lang="java">

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

  • /</source>





Converting Between a BitSet and a Byte Array

   <source lang="java">

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}</source>





Demonstrate the bitwise logical operators

   <source lang="java">

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]);
 }

}</source>



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


Left shift (<<)

   <source lang="java">

public class Main {

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

} //1152</source>





Left shifting as a quick way to multiply by 2

   <source lang="java">

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);
   }
 }

}</source>



536870908
1073741816
2147483632
-32


Operations on bit-mapped fields.

   <source lang="java">

/*

* 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 true if any of the bits are set,
    *  else false
    */
   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 true.
    *
    * @param holder the int data containing the bits we"re
    *  interested in
    * @return true if all of the bits are set,
    *  else false
    */
   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 0)
    */
   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 0)
    */
   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 0)
    */
   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 1
    */
   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 1
    */
   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 1
    */
   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);
   }

}</source>





Performing Bitwise Operations on a Bit Vector

   <source lang="java">

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); 
 }

}</source>





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

   <source lang="java">

/*

* 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,
* Flag 1 = 1
* Flag 2 = 2
* Flag 3 = 4
* Flag 4 = 8

* or using shift operator to make numbering easier:
* Flag 1 = 1 << 0
* Flag 2 = 1 << 1
* Flag 3 = 1 << 2
* Flag 4 = 1 << 3
* * * 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 turnOffAll().
    * @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();
   }

}</source>





Returns a byte array of at least length 1

   <source lang="java">

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;
 }

}</source>





Signed shift to the right

   <source lang="java">

public class Main {

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

}</source>





The Bitwise Logical Operators

   <source lang="java">

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</source>
   
  
 
  



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

   <source lang="java">

// 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);
 }

}</source>



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


The Right Shift

   <source lang="java">

public class MainClass {

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

}</source>





The Unsigned Right Shift

   <source lang="java">

public class MainClass {

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

}</source>



255


Unsigned shifting a byte value.

   <source lang="java">

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]);
 }

}</source>



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


Use bitwise operator to create hash code

   <source lang="java">

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);
 }

}</source>