Invert a value of bit in digit

162 views Asked by At

I want to invert a value of bit in digit.

The method should invert value by number of bit, like this:

public static void main(String[] args) {

    int res = flipBit(7,1);
}

public static int flipBit(int value, int bitIndex) {

    String bin = Integer.toBinaryString(value);
    char newChar = (char) (bin.charAt(bitIndex) ^ bin.charAt(bitIndex));
    
    //pseudo code
    bin[bitIndex] = newChar;    
    
    return Integer.parseInt(bin);
}
3

There are 3 answers

8
Alexander Ivanchenko On BEST ANSWER

Mixing mix bitwise operations and strings will not improve the performance and reduces the redubility of code.

Assuming that bitIndex is zero-based, it might be done using XOR operator like that (credits to @Iłya Bursov since he has pointed out it earlier in the comments):

public static int flipBit(int value, int bitIndex) {
    if (bitIndex < 0 || bitIndex > 31) {
        throw new IllegalArgumentException();
    }
    
    return value ^ 1 << bitIndex;
}

Online Demo

A quick recap on how XOR works.

1 ^ 1  =>  0
0 ^ 1  =>  1
1 ^ 0  =>  1
0 ^ 0  =>  0

That means zeros 0 in the bit-mask 1 << bitIndex, created by shifting the value of 1 by the given index, will have no impact on the result while applying XOR.

Only a single significant bit of the mask would interact with the value: if it would encounter 1, this bit would be turned into 0, or if there would be 0 at the same position it would result into 1.

Example:

value = 7, index = 2

111   -   value
 ^
100   -   bit-mask `1 << bitIndex`

011   -   result is `3`

value = 0, index = 0

000   -   value
 ^
001   -   bit-mask `1 << bitIndex`

001   -   result is `1`
2
Stewart On

How about:

String bin = Integer.toBinaryString( value );
char newChar = (char) (bin.charAt(bitIndex) ^ bin.charAt(bitIndex));

StringBuilder sb = new StringBuilder( bin );
sb.setCharAt( bitIndex, newChar );
return sb.toString();
0
Franck On

This solution refers to:

I have string of binary in bin like "111" = 7. I need to change a bit in position bitIndex.

Currently bitIndex is zero-based and counted from the front of the string. (This might not be desired and could be changed with the use of bitIndex = binaryText.length() - 1 - bitIndex;)

public class Main
{
    public static void main(String[] args) {
        String bin = Integer.toBinaryString(7);
        int bitIndex = 2;
        System.out.println("Original string:         " + bin);
        System.out.println("String with flipped bit: " + flipBit(bin, 2));
        try {
            System.out.println("Flipping using number:   " + flipBitViaNumber(bin, 2));    
        } catch (NumberFormatException ex) {
            System.err.println("Oops! Not a number: " + bin);
        }
        System.out.println("Flipping via char array: " + flipBitViaCharArray(bin, 2));
    }
    
    public static String flipBit(String binaryText, int bitIndex) {
        StringBuilder sb = new StringBuilder(binaryText.length());
        for (int i = 0; i < binaryText.length(); i++) {
            if (i == bitIndex) {
                 sb.append(binaryText.charAt(i) == '1' ? '0' : '1');
            } else {
                sb.append(binaryText.charAt(i));
            }
        }
        return sb.toString();
    }

    public static String flipBitViaNumber(String binaryText, int bitIndex) 
        throws  NumberFormatException {

        int value = Integer.parseInt(binaryText, 2);
        int pattern = 1 << (binaryText.length() - 1 - bitIndex);
        value = value ^ pattern;
        return Integer.toBinaryString(value);
    }
    
    public static String flipBitViaCharArray(String binaryText, int bitIndex) 
        throws  NumberFormatException {

        char[] chars = binaryText.toCharArray();
        chars[bitIndex] = chars[bitIndex] == '1' ? '0' : '1';
        return new String(chars);
    }    
}
Original string:         111
String with flipped bit: 110
Flipping using number:   110
Flipping via char array: 110

Additional information

A Java int consists of 32 bits, see https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html. Java uses the *two's complement as binary representation. Bitwise operations on ints are handled on the Java stack with particular bytecodes which are very fast as neither objects nor method invocations are used.