java 按位否定给出了意想不到的结果
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15575520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Bitwise negation gives unexpected result
提问by Josh Sobel
I am trying to write a bitwise calculator in java, something that you could input an expression such as ~101 and it would give back 10 however when i run this code
我正在尝试用 Java 编写一个按位计算器,您可以输入诸如 ~101 之类的表达式,但是当我运行此代码时它会返回 10
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
Integer a = Integer.valueOf("101", 2);
System.out.println(Integer.toString(~a,2));
}
}
it outputs -110 why?
它输出-110 为什么?
回答by Edwin Buck
You are assuming that 101 is three bits long. Java doesn't support variable length bit operations, it operates on a whole intof bits, so ~will be the notof a 32 bit long "101".
您假设 101 是三位长。Java不支持可变长度的位操作,在整个操作int的位,所以~将是not一个32位长的“101”。
--- Edited after being asked "How can I fix this?" ---
--- 在被问到“我该如何解决这个问题?”后编辑 ---
That's a really good question, but the answer is a mix of "you can't" and "you can achieve the same thing by different means".
这是一个非常好的问题,但答案是“你不能”和“你可以通过不同的方式实现同样的目标”的混合。
You can't fix the ~operator, as it does what it does. It would sort of be like asking to fix +to only add the 1's place. Just not going to happen.
您无法修复~操作员,因为它会做它所做的事情。这有点像要求修复+只添加 1 的位置。只是不会发生。
You can achieve the desired operation, but you need a bit more "stuff" to get it going. First you must have something(another int) that specifies the bits of interest. This is typically called a bit mask.
您可以实现所需的操作,但您需要更多的“东西”才能让它运行。首先,你必须有一些东西(另一个 int)来指定感兴趣的位。这通常称为位掩码。
int mask = 0x00000007; // just the last 3 bits.
int masked_inverse = (~value) & mask;
Note that what we did was really invert 32 bits, then zeroed out 29 of those bits; because, they were set to zero in the mask, which means "we don't care about them". This can also be imagined as leveraging the &operator such that we say "if set and we care about it, set it".
请注意,我们所做的实际上是反转 32 位,然后将其中的 29 位归零;因为,它们在掩码中被设置为零,这意味着“我们不关心它们”。这也可以想象为利用&操作符,这样我们说“如果设置并且我们关心它,就设置它”。
Now you will stillhave 32 bits, but only the lower 3 will be inverted. If you want a 3 bit data structure, then that's a different story. Java (and most languages) just don't support such things directly. So, you might be tempted to add another typeto Java to support that. Java adds types via a classmechanism, but the built-in types are not changeable. This means you could write a class to represent a 3 bit data structure, but it will have to handle ints internally as 32 bit fields.
现在你仍然有 32 位,但只有低 3 位会被反转。如果你想要一个 3 位的数据结构,那就是另一回事了。Java(和大多数语言)只是不直接支持这些东西。因此,您可能会想向 Java添加另一种类型来支持它。Java 通过类机制添加类型,但内置类型是不可更改的。这意味着您可以编写一个类来表示 3 位数据结构,但它必须在内部将整数处理为 32 位字段。
Fortunately for you, someone has already done this. It is part of the standard Java library, and is called a BitSet.
幸运的是,有人已经这样做了。它是标准 Java 库的一部分,称为BitSet.
BitSet threeBits = new BitSet(3);
threeBits.set(2); // set bit index 2
threeBits.set(0); // set bit index 0
threeBits.flip(0,3);
However, such bit manipulations have a different feel to them due to the constraints of the Class / Object system in Java, which follows from defining classes as the only wayto add new types in Java.
然而,由于 Java 中类 / 对象系统的限制,这种位操作对它们有不同的感觉,这是因为将类定义为在 Java 中添加新类型的唯一方法。
回答by Pshemo
If a = ...0000101 (bin) = 5 (dec)
如果 a = ...0000101 (bin) = 5 (dec)
~a = ~...0000101(bin) = ...1111010(bin)
and Java uses "Two's complement" form to represent negative numbers so
而Java使用“二进制补码”的形式来表示负数,所以
~a = -6 (dec)
Now difference between Integer.toBinaryString(number)and Integer.toString(number, 2)for negative number is that
现在负数Integer.toBinaryString(number)和Integer.toString(number, 2)负数的区别在于
toBinaryStringreturns String in "Two's complement" form buttoString(number, 2)calculates binary form as if number was positive and add "minus" mark if argument was negative.
toBinaryString以“二进制补码”形式返回字符串,但toString(number, 2)计算二进制形式,就好像数字是正数一样,如果参数是负数,则添加“减号”标记。
So toString(number, 2)for ~a = -6will
所以toString(number, 2)为了~a = -6意志
- calculate binary value for
6->0000110, - trim leading zeros ->
110, - add minus mark ->
-110.
- 计算二进制值
6->0000110, - 修剪前导零 ->
110, - 添加减号 ->
-110。
回答by David Levy
Just to elaborate on Edwin's answer a bit - if you're looking to create a variable length mask to develop the bits of interest, you might want some helper functions:
只是为了详细说明 Edwin 的回答 - 如果您想创建一个可变长度掩码来开发感兴趣的位,您可能需要一些辅助函数:
/**
* Negate a number, specifying the bits of interest.
*
* Negating 52 with an interest of 6 would result in 11 (from 110100 to 001011).
* Negating 0 with an interest of 32 would result in -1 (equivalent to ~0).
*
* @param number the number to negate.
* @param bitsOfInterest the bits we're interested in limiting ourself to (32 maximum).
* @return the negated number.
*/
public int negate(int number, int bitsOfInterest) {
int negated = ~number;
int mask = ~0 >>> (32 - bitsOfInterest);
logger.info("Mask for negation is [" + Integer.toBinaryString(mask) + "]");
return negated & mask;
}
/**
* Negate a number, assuming we're interesting in negation of all 31 bits (exluding the sign).
*
* Negating 32 in this case would result in ({@link Integer#MAX_VALUE} - 32).
*
* @param number the number to negate.
* @return the negated number.
*/
public int negate(int number) {
return negate(number, 31);
}
回答by Joni
The toString() method interprets its argument as a signed value.
toString() 方法将其参数解释为有符号值。
To demonstrate binary operations its better to use Integer.toBinaryString(). It interprets its argument as unsigned, so that ~101 is output as 11111111111111111111111111111010.
为了演示二进制操作,最好使用Integer.toBinaryString(). 它将其参数解释为无符号,因此 ~101 输出为 11111111111111111111111111111010。
If you want fewer bits of output you can mask the result with &.
如果你想要更少的输出位,你可以用 & 屏蔽结果。
回答by enigma
101 in integer is actually represented as 00000000000000000000000000000101negate this and you get 11111111111111111111111111111010- this is -6.
整数中的 101 实际上表示为00000000000000000000000000000101否定 this 并且您得到11111111111111111111111111111010- 这是-6.

