【问题标题】:What does value & 0xff do in Java?Java 中 value 和 0xff 有什么作用?
【发布时间】:2012-07-07 23:12:04
【问题描述】:

我有以下 Java 代码:

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

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

【问题讨论】:

  • 我将代码复制到 Eclipse。它警告我“类型不匹配:无法从 int 转换为字节”。是否应该更改为 int value = 0xfe;
  • @BenCheng 应该是byte value = (byte) 0xfe;

标签: java integer byte bitwise-and


【解决方案1】:

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

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

int result = value;

那么result 会以ff 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嗯,不完全是。如果任一操作数是 long& 运算符也适用于 long 值。但不在byte 上。请参阅 Java 语言规范,15.22.15.6.2 部分。

【讨论】:

  • 该符号中的 x 是什么意思? x 不是数字或十六进制数字?
  • @KazRodgers - 0x(或0X)前缀告诉Java后面的整数文字应该被解释为十六进制(以16为基数)。 Java 还支持八进制文字的裸 0 前缀和二进制文字的 0b(或 0B)前缀。有关整数文字的更多信息,请参阅Java Language Specification
  • 接下来的文字?例如,如果我有 0x3fa。 3fa 是被翻译成文字数字的部分,而 0x 表示“这是一个十六进制数字”? @TedHopp?
  • @KazRodgers - 没错。请注意,0x0b 本身(后面没有任何数字)在 Java 中是非法语法。
  • @DmitryMinkovsky - 8 位的十六进制位模式fe,二进制补码对应于十进制值 -2。为了保留该值,Integer.valueOf(byte) 需要生成 ff ff ff fe(32 位中的 -2,二进制补码),而不是 00 00 00 fe(十进制值 254)。这种转换(从bytefeintff ff ff fe)称为sign extension,是Java 语言规范的一部分。 value & 0xff 的目的是撤消符号扩展(即模拟零扩展,Java 没有)。
【解决方案2】:

来自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

& 类似于 % 但不是 really

为什么是 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;

ReSet(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 :)

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;
【解决方案3】:

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

【讨论】:

  • 你能再解释一下吗?
【解决方案4】:

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

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

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

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

Great Explanation See here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 2017-05-26
    • 2015-07-23
    • 1970-01-01
    • 2016-02-27
    • 2018-05-22
    • 1970-01-01
    相关资源
    最近更新 更多