113

我有以下 Java 代码:

byte value = 0xfe; // corresponds to -2 (signed) and 254 (unsigned)
int result = value & 0xff;

打印时的结果是 254,但我不知道这段代码是如何工作的。如果&运算符只是按位的,那么为什么它不会产生一个字节而是一个整数呢?

4

4 回答 4

183

它设置result为(无符号)值,将 的 8 位value放在 的最低 8 位中result

之所以需要这样的东西是因为它byte是 Java 中的签名类型。如果你刚刚写了:

int result = value;

那么result最终会得到 valueff ff ff fe而不是00 00 00 fe. 另一个微妙之处在于&被定义为仅对int1进行操作,所以会发生什么:

  1. value被提升为int( ff ff ff fe)。
  2. 0xffint文字 ( 00 00 00 ff)。
  3. &用于产生 的所需值result

(关键是转换为int发生运算符&应用之前。)

1嗯,不完全是。如果任一操作数是 a ,则该&运算符也适用于值。但不上。请参阅 Java 语言规范,第15.22.15.6.2节。longlongbyte

于 2012-07-08T01:50:03.120 回答
66

来自http://www.coderanch.com/t/236675/java-programmer-SCJP/certification/xff

十六进制文字 0xFF 是一个相等的 int(255)。Java 将 int 表示为 32 位。二进制看起来像这样:

00000000 00000000 00000000 11111111

当您对任何数字使用此值(255)进行一点与操作时,它将屏蔽(使零)除数字的最低 8 位之外的所有位(将保持原样)。

... 01100100 00000101 & ...00000000 11111111 = 00000000 00000101

& 类似于 % 但不是真的

为什么是0xff?这在 ((2 的幂) - 1) 中。所有 ((2 的幂) - 1) (例如 7, 255...) 的行为类似于 % 运算符。

然后
在二进制中,0 是,全为零,255 看起来像这样:

00000000 00000000 00000000 11111111

-1 看起来像这样

11111111 11111111 11111111 11111111

当您对 0xFF 和 0 到 255 之间的任何值进行按位与运算时,结果与该值完全相同。如果任何值高于 255,结果仍将在 0-255 之间。

但是,如果您这样做:

-1 & 0xFF

你得到

00000000 00000000 00000000 11111111,它不等于 -1 的原始值(11111111十进制为 255)。


更多位操作:(与问题无关)

X >> 1 = X/2
X << 1 = 2X

检查任何特定位是否设置(1)或不设置(0)然后

 int thirdBitTobeChecked =   1 << 2   (...0000100)
 int onWhichThisHasTobeTested = 5     (.......101)

 int isBitSet = onWhichThisHasTobeTested  & thirdBitTobeChecked;
 if(isBitSet > 0) {
  //Third Bit is set to 1 
 } 

设置(1)一个特定的位

 int thirdBitTobeSet =   1 << 2    (...0000100)
 int onWhichThisHasTobeSet = 2     (.......010)
 onWhichThisHasTobeSet |= thirdBitTobeSet;

重置(0)特定位

int thirdBitTobeReSet =   ~(1 << 2)  ; //(...1111011)
int onWhichThisHasTobeReSet = 6      ;//(.....000110)
onWhichThisHasTobeReSet &= thirdBitTobeReSet;

异或

请注意,如果您执行两次异或运算,将得到相同的值。

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

byte encryptedVal  =  toBeEncrypted ^ salt == 0110 1101
byte decryptedVal  =  encryptedVal  ^ salt == 0010 0110 == toBeEncrypted :)

异或的另一种逻辑是

if     A (XOR) B == C (salt)
then   C (XOR) B == A
       C (XOR) A == B

以上对于在没有 temp 的情况下交换两个变量很有用,如下所示

a = a ^ b; b = a ^ b; a = a ^ b;

或者

a ^= b ^= a ^= b;
于 2014-05-22T08:32:50.923 回答
5

它有助于减少大量代码。它偶尔用于由 8 位组成的 RGB 值。

其中 0xff 表示 24(0's ) 和 8(1's) 之类的00000000 00000000 00000000 11111111

它有效地掩盖了变量,因此它只留下最后 8 位中的值,并忽略所有其余位

在尝试将颜色值从特殊格式转换为标准 RGB 值(8 位长)等情况下最常见。

很好的解释看这里

于 2015-04-17T14:53:31.617 回答
0

在 32 位格式系统中,十六进制值表示0xff十进制。并且按位 & 运算符屏蔽与第一个操作数相同的 8 个最右边的位。00000000000000000000000011111111255(15*16^1+15*16^0)

于 2015-05-03T17:59:03.833 回答