value&0xff在Java中有什么作用?


101

我有以下Java代码:

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

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


我将代码复制到Eclipse。它警告我“类型不匹配:无法从int转换为byte”。是否应更改为int值= 0xfe;
Ben Cheng

1
@BenCheng应该是byte value = (byte) 0xfe;
Bek

Answers:


173

它将设置result为通过将的8位value放入的最低8位得到的(无符号)值result

之所以需要这样的原因是因为它byte是Java中的一种签名类型。如果您刚刚写过:

int result = value;

然后result将以值ff ff ff fe代替00 00 00 fe。另一个微妙之处是,将&定义为仅对int1进行操作,因此会发生以下情况:

  1. value被提升为intff ff ff fe)。
  2. 0xffint文字(00 00 00 ff)。
  3. &被施加到得到所希望的值result

(该点是,转换int发生之前&施加操作者)。

1 好吧,不完全是。该&运营商工作的long价值以及,如果操作数是一个long。但是没有byte。请参阅Java语言规范的15.22.15.6.2节。


x在该表示法中是什么意思?x是数字还是十六进制数字?
卡拉特

3
@KazRodgers- 0x(或0X)前缀告诉Java,其后的整数文字应解释为十六进制(基数为16)。Java还支持0八进制文字的裸前缀和二进制文字的0b(或0B)前缀。有关整数文字的更多信息,请参见Java语言规范
泰德·霍普

接下来的文字?例如,如果我有0x3fa。3fa是要转换为文字数字的部分,而0x是否指出“这是十六进制数字”?@TedHopp?
卡亚特

1
@KazRodgers-是的。请注意,在Java中,0x0b本身(后面没有任何数字)是非法语法。
特德·霍普

1
@DmitryMinkovsky- fe以8位二进制补码表示的十六进制位模式对应于十进制值-2。为了保留该值,Integer.valueOf(byte)将需要产生ff ff ff fe(32位中的-2,二进制补码),而不是00 00 00 fe(十进制值254)。这种转换(从bytefeintvalue ff ff ff fe)被称为符号扩展,并且是Java语言规范的一部分。的目的value & 0xff是撤消符号扩展(即,模拟零扩展,这是Java所没有的)。
泰德·霍普

57

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之间的任何值进行按位AND运算时,结果与该值完全相同。并且如果任何值大于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;

异或

请注意,如果执行两次XOR操作,将得到相同的值。

byte toBeEncrypted = 0010 0110
byte salt          = 0100 1011

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

XOR的另一种逻辑是

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;



5

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

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

它有效地屏蔽了变量,因此只保留了最后8位中的值,而忽略了其余所有位

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

很棒的解释请看这里


0

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


你能再解释一下吗
ashishdhiman2007 '17
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.