Ande Turner
Ande Turner

Reputation: 7212

Java: Checking if a bit is 0 or 1 in a long

What method would you use to determine if the the bit that represents 2^x is a 1 or 0 ?

Upvotes: 86

Views: 93294

Answers (14)

rslemos
rslemos

Reputation: 2730

In Java the following works fine:

if (value << ~x < 0) {
   // xth bit set
} else {
   // xth bit not set
}

value and x can be int or long (and don't need to be the same).

Word of caution for non-Java programmers: the preceding expression works in Java because in that language the bit shift operators apply only to the 5 (or 6, in case of long) lowest bits of the right hand side operand. This implicitly translates the expression to value << (~x & 31) (or value << (~x & 63) if value is long).

Javascript: it also works in javascript (like java, only the lowest 5 bits of shift count are applied). In javascript any number is 32-bit.

Particularly in C, negative shift count invokes undefined behavior, so this test won't necessarily work (though it may, depending on your particular combination of compiler/processor).

How does it work?

The cleverness of this answer lies in that the sign bit of an integer is very easy to read: when that bit is set, then the value is negative; if not set, then the value is either zero or positive.

So the whole idea is to shift the xth bit exactly into the sign bit. That means a displacement of 31 - x to the left (or 63 - x, if value is 64 bits wide).

In java (and other languages as well), the ~ operator computes the bitwise NOT operation, which arithmetically equals to -x - 1 (no matter how wide x is).

Also the java << operator takes only the least significant 5 (or 6) bits of the right-hand side operand (whether 5 or 6 depends on how wide the left-hand side operand is: for int then 5; for long then 6). Arithmetically this is the same as the remainder of division by 32 (or 64).

And that is (-x - 1) % 32 = 31 - x (or (-x - 1) % 64 = 63 - x, for 64 bit wide value).

Upvotes: 5

Jon Skeet
Jon Skeet

Reputation: 1500993

I'd use:

if ((value & (1L << x)) != 0)
{
   // The bit was set
}

(You may be able to get away with fewer brackets, but I never remember the precedence of bitwise operations.)

Upvotes: 192

Alessandro Giusa
Alessandro Giusa

Reputation: 1768

I coded a little static class which is doing some of the bit operation stuff.

public final class Bitfield {

  private Bitfield() {}

  // ********************************************************************
  // * TEST
  // ********************************************************************

  public static boolean testBit(final int pos, final int bitfield) {
      return (bitfield & (1 << pos)) == (1 << pos);
  }

  public static boolean testNum(final int num, final int bitfield) {
      return (bitfield & num) == num;
  }

  // ********************************************************************
  // * SET
  // ********************************************************************

  public static int setBit(final int pos, final int bitfield) {
     return bitfield | (1 << pos);
  }

  public static int addNum(final int number, final int bitfield) {
      return bitfield | number;
  }

  // ********************************************************************
  // * CLEAR
  // ********************************************************************

  public static int clearBit(final int pos, final int bitfield) {
      return bitfield ^ (1 << pos);
  }

  public static int clearNum(final int num, final int bitfield) {
      return bitfield ^ num;
  }

  }

If there are some questions flying around, just write me an email.

Good Programming!

Upvotes: 0

Kaushik Lele
Kaushik Lele

Reputation: 6637

If someone is not very comfortable with bitwise operators, then below code can be tried to programatically decide it. There are two ways.

1) Use java language functionality to get the binary format string and then check character at specific position

2) Keep dividing by 2 and decide the bit value at certain position.

public static void main(String[] args) {
    Integer n =1000;
    String binaryFormat =  Integer.toString(n, 2);
    int binaryFormatLength = binaryFormat.length();
    System.out.println("binaryFormat="+binaryFormat);
    for(int i = 1;i<10;i++){
        System.out.println("isBitSet("+n+","+i+")"+isBitSet(n,i));
        System.out.println((binaryFormatLength>=i && binaryFormat.charAt(binaryFormatLength-i)=='1'));
    }

}

public static boolean isBitSet(int number, int position){
    int currPos =1;
    int temp = number;
    while(number!=0 && currPos<= position){
        if(temp%2 == 1 && currPos == position)
            return true;
        else{
            temp = temp/2;
            currPos ++;
        }
    }
    return false;
}

Output

binaryFormat=1111101000
isBitSet(1000,1)false
false
isBitSet(1000,2)false
false
isBitSet(1000,3)false
false
isBitSet(1000,4)true
true
isBitSet(1000,5)false
false
isBitSet(1000,6)true
true
isBitSet(1000,7)true
true
isBitSet(1000,8)true
true
isBitSet(1000,9)true
true

Upvotes: 1

user1893702
user1893702

Reputation:

declare a temp int and make it equal the original. then shift temp >> x times, so that the bit you want to check is at the last position. then do temp & 0xf to drop the preceding bits. Now left with last bit. Finally do if (y & 1 == 0), if last bit is a 1, that should equal 0, else will equal 1. Its either that or if (y+0x1 == 0)... not too sure. fool around and see

Upvotes: 0

My contribution - ignore previous one

public class TestBits { 

    public static void main(String[] args) { 

        byte bit1 = 0b00000001;     
        byte bit2 = 0b00000010;
        byte bit3 = 0b00000100;
        byte bit4 = 0b00001000;
        byte bit5 = 0b00010000;
        byte bit6 = 0b00100000;
        byte bit7 = 0b01000000;

        byte myValue = 9;                        // any value

        if (((myValue >>> 3) & bit1 ) != 0) {    //  shift 3 to test bit4
            System.out.println(" ON "); 
        }
    } 
}

Upvotes: 1

Noldorin
Noldorin

Reputation: 147360

For the nth LSB (least significant bit), the following should work:

boolean isSet = (value & (1 << n)) != 0;

Upvotes: 8

Ande Turner
Ande Turner

Reputation: 7212

I wonder if:

  if (((value >>> x) & 1) != 0) {

  }

.. is better because it doesn't matter whether value is long or not, or if its worse because it's less obvious.

Tom Hawtin - tackline Jul 7 at 14:16

Upvotes: 16

typeseven
typeseven

Reputation: 810

Eliminate the bitshifting and its intricacies and use a LUT for the right and operand.

Upvotes: -2

Yannick Motton
Yannick Motton

Reputation: 35971

You might want to check out BitSet: http://java.sun.com/javase/6/docs/api/java/util/BitSet.html

Upvotes: 7

finnw
finnw

Reputation: 48629

Another alternative:

if (BigInteger.valueOf(value).testBit(x)) {
    // ...
}

Upvotes: 102

ThibThib
ThibThib

Reputation: 8210

You can also use

bool isSet = ((value>>x) & 1) != 0;

EDIT: the difference between "(value>>x) & 1" and "value & (1<<x)" relies on the behavior when x is greater than the size of the type of "value" (32 in your case).

In that particular case, with "(value>>x) & 1" you will have the sign of value, whereas you get a 0 with "value & (1<<x)" (it is sometimes useful to get the bit sign if x is too large).

If you prefer to have a 0 in that case, you can use the ">>>" operator, instead if ">>"

So, "((value>>>x) & 1) != 0" and "(value & (1<<x)) != 0" are completely equivalent

Upvotes: 13

schnaader
schnaader

Reputation: 49719

Bit shifting right by x and checking the lowest bit.

Upvotes: 4

Artur Soler
Artur Soler

Reputation: 3024

The value of the 2^x bit is "variable & (1 << x)"

Upvotes: 2

Related Questions