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 int
of bits, so ~
will be the not
of 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)
负数的区别在于
toBinaryString
returns 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 = -6
will
所以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 00000000000000000000000000000101
negate this and you get 11111111111111111111111111111010
- this is -6
.
整数中的 101 实际上表示为00000000000000000000000000000101
否定 this 并且您得到11111111111111111111111111111010
- 这是-6
.