将位的值反转为数字
Invert a value of bit in digit
我想反转位的数字值。
该方法应按位数反转值,如下所示:
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);
}
怎么样:
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();
混合按位运算和字符串不会提高性能并降低代码的可重复性。
假设 bitIndex
是 zero-based,可以使用像这样的 XOR 运算符来完成(归功于 @Iłya Bursov,因为他已经指出了这一点在评论的前面):
public static int flipBit(int value, int bitIndex) {
if (bitIndex < 0 || bitIndex > 31) {
throw new IllegalArgumentException();
}
return value ^ 1 << bitIndex;
}
快速回顾 XOR 的工作原理。
1 ^ 1 => 0
0 ^ 1 => 1
1 ^ 0 => 1
0 ^ 0 => 0
这意味着 bit-mask 1 << bitIndex
中的零 0
,通过将 1
的值按给定索引移动而创建,不会对结果产生影响,而应用异或。
只有掩码的单个有效位会与值交互:如果它会遇到1
,这个位会变成0
,或者如果在同一个位置有0
,它会变成1
。
示例:
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`
本方案参考:
I have string of binary in bin like "111" = 7. I need to change a bit in position bitIndex.
目前bitIndex是zero-based,从字符串的前面算起。 (这可能不是我们想要的,可以使用 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
附加信息
A Java int 由 32 位组成,参见 https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html. Java uses the *two's complement 作为二进制表示。对 int 的按位操作在 Java 堆栈上处理,具有特定的字节码,这些字节码非常快,因为既不使用对象也不使用方法调用。
我想反转位的数字值。
该方法应按位数反转值,如下所示:
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);
}
怎么样:
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();
混合按位运算和字符串不会提高性能并降低代码的可重复性。
假设 bitIndex
是 zero-based,可以使用像这样的 XOR 运算符来完成(归功于 @Iłya Bursov,因为他已经指出了这一点在评论的前面):
public static int flipBit(int value, int bitIndex) {
if (bitIndex < 0 || bitIndex > 31) {
throw new IllegalArgumentException();
}
return value ^ 1 << bitIndex;
}
快速回顾 XOR 的工作原理。
1 ^ 1 => 0
0 ^ 1 => 1
1 ^ 0 => 1
0 ^ 0 => 0
这意味着 bit-mask 1 << bitIndex
中的零 0
,通过将 1
的值按给定索引移动而创建,不会对结果产生影响,而应用异或。
只有掩码的单个有效位会与值交互:如果它会遇到1
,这个位会变成0
,或者如果在同一个位置有0
,它会变成1
。
示例:
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`
本方案参考:
I have string of binary in bin like "111" = 7. I need to change a bit in position bitIndex.
目前bitIndex是zero-based,从字符串的前面算起。 (这可能不是我们想要的,可以使用 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
附加信息
A Java int 由 32 位组成,参见 https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html. Java uses the *two's complement 作为二进制表示。对 int 的按位操作在 Java 堆栈上处理,具有特定的字节码,这些字节码非常快,因为既不使用对象也不使用方法调用。