我试图用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));
}
}
它输出-110为什么呢?
你是假设101是3位长。 Java不支持可变长度的位操作,在整个操作int
位的,所以~
将是not
的一个32位长的“101”。
---被要求编后:“我怎样才能解决这个问题?” ---
这是一个非常好的问题,但得到的答复是“你不能”和“你可以通过不同的方式达到同样的事情”的混合体。
你不能修复~
运营商,因为它它做什么。 它会有点像,询问修复+
只加1的位置。 只是不会发生。
你可以达到理想的操作,但你需要多一点“东西”开始下载。 首先,你必须拥有的东西 (另一个INT),指定感兴趣的位 。 这通常称为位掩码 。
int mask = 0x00000007; // just the last 3 bits.
int masked_inverse = (~value) & mask;
请注意,我们所做的事情是真的反转32位,则清零这些位的29; 因为,他们的面具,这意味着“我们不关心他们”被设置为零。 这也可以被想象成撬动&
操作,使得我们说:“如果设置,我们关心它,把它”。
现在,你仍然有32位,但仅低3将被反转。 如果你想有一个3位数据结构,那么这是一个不同的故事。 Java语言(大多数语言),只是不直接支持这样的事情。 所以,你可能会为另一种类型添加到Java来支持。 通过Java的一个类机构增加了类型,但内置的类型是不可改变的。 这意味着你可以写一个类来表示一个3位数据结构,但它必须在内部处理整数为32个字段。
幸运的是,有人已经做到了这一点。 这是标准的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);
然而,这样的位操作有不同的感觉,他们由于在Java类/对象系统中,从定义类为Java中添加新类型的必由之路随后的制约。
如果a = ...0000101 (bin) = 5 (dec)
~a = ~...0000101(bin) = ...1111010(bin)
和Java使用“ 两补 ”的形式来表示负数所以
~a = -6 (dec)
现在之间差Integer.toBinaryString(number)
和Integer.toString(number, 2)
为负数是
-
toBinaryString
在“返回字符串两补 ”的形式,但 -
toString(number, 2)
计算二进制形式仿佛数为正,并添加“负”标志,如果自变量为阴性。
这样toString(number, 2)
为~a = -6
意愿
- 用于计算二进制值
6
- > 0000110
, - 修剪前导零- >
110
, - 加负马克- >
-110
。
101整数实际上表示为00000000000000000000000000000101
否定这一点,你会得到11111111111111111111111111111010
-这是-6
。
的toString()方法解释其作为带符号的值的参数。
为了证明二进制运算它能够更好地使用Integer.toBinaryString()
它解释其参数为无符号,所以〜101输出为11111111111111111111111111111010。
如果你想输出的较少比特可以屏蔽与和结果。
只是对埃德温的回答详细一点 - 如果你正在寻找创建一个可变长度的面具开发感兴趣的位,你可能需要一些辅助功能:
/**
* 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);
}