0

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); } 
5
  • 3
    return value ^ (1 << bitIndex); ? Commented May 22, 2022 at 19:57
  • I have string of binary in <bin> like "111" = 7. I need to change a bit in position <bitIndex>. Commented May 22, 2022 at 20:03
  • 2
    where do you have it? in source code posted value is integer Commented May 22, 2022 at 20:04
  • this line returns a string of binary: String bin = Integer.toBinaryString(value); // bin = "111" Commented May 23, 2022 at 5:27
  • hm, aren't you getting it from value which is integer? why do you need derivative when you have originally passed value? Commented May 24, 2022 at 2:14

3 Answers 3

5

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` 
Sign up to request clarification or add additional context in comments.

8 Comments

It's also worth noting that this code is extremely faster than dealing with strings.
this is not correct, because in case of value == 0, it returns 2, correct answer is 1.
@Anatoly You mean when the value is 0 and bitIndex is 0 ? Then the correct result will be 1, and that exactly what this code will return.
@Anatoly If you would pass 1 as the argument of bitIndex, you'll get 2 as a result.
@BadrB More important that there's no need to mix strings with bitwise operations. Dealing with a string of 30 characters would not cause a huge performance hit. If this approach would bring an advantage in terms of readability of the code, it might be worth to pay this cost. But in this case it doesn't, a jumble of bitwise operations and strings will only create a confusion.
|
0

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.

Comments

-2

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

2 Comments

shouldn't we expect 0 (integer) from (bin.charAt(bitIndex) ^ bin.charAt(bitIndex)) , no matter which value is at that position? And (char) 0 is not same as '0'?
I tried this, and <sb> suddenly cuts value: StringBuilder sb = new StringBuilder(bin); sb.setCharAt(bitIndex, newChar); bin = sb.toString(); // sb becomes "11", loses one bit. should be "110"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.