Java OR 操作员发疯了
Java OR operator going insane
冒着未来几天感到羞愧的风险...请向我解释以下内容。
我需要用字节对整数进行算术运算。
int a = 0x0100;
byte b = (byte)0xff;
int c = a | b;
我希望 c 为 0x100 | 0xff = 0x1ff = 511
。
但它是 0xffffffff = -1
为什么?
b
是 -1
。
当您执行 a | b
时,b
被提升为仍然是 -1
.
的 int
15.22.1. Integer Bitwise Operators &, ^, and |
When both operands of an operator &, ^, or |
are of a type that is convertible (§5.1.8) to a primitive integral type,
binary numeric promotion is first performed on the operands (§5.6.2).
因此,a | b
的计算结果如同 a | -1
。
final int a = 0x0100;
final int b = 0xFF;
final int c = a | b;
我不确定你到底想做什么,但是。
How could I accomplish adding 8 bits to the end of a int value in simple steps?
int appendDummyOnes(final int value, final int size) {
return (value << size) | (-1 >>> (Integer.SIZE - size));
}
int remarkDummyOnes(final int value, final int size) {
return value | (-1 >>> (Integer.SIZE - size));
}
这个有效:
int c = a | (b & 0xff);
在您的代码中
int c = a | b;
byte b 扩展为 int 并保留值(-1 表示此值在 signed int 中)。
这个值在int中是0xFFffFFff,所以在0x0100 |之后0xFFffFFff 你得到了 0xFFffFFff
如 Jin Kwon 的回答所述 - 在当前情况下您应该使用整数。
中解释了保留行为的原因。但请注意,有一个简单的解决方案(除了其他答案中提到的 (b & 0xFF)
之外): Java 8 添加了一些处理无符号值的便捷方法。所以你可以简单地做
int c = a | Byte.toUnsignedInt(b);
我将此用于您的代码。您的代码变得疯狂的原因是:
You were using integer (int) data type which is of 1 byte (8 bit) but you were processing data of 2 bytes (16 bits). In such cases, the MSB (8th bit) is taken as sign bit which is 0 for (-ve) and 1 for(+ve).
事实上,OR 运算符并没有发疯,这是您的代码。您可以使用类似于下面的实现来使您的代码运行良好:
import java.io.*;
import java.util.*;
class Lesson7{
public static void main(String args[]){
int a = 0x01;
byte b = (byte)0x00;
int c = a | b;
System.out.println(c);
}
}
我测试过这个:
int a = 0x100;
int b = 0xff;
int c = a|b;
System.out.println(c);
冒着未来几天感到羞愧的风险...请向我解释以下内容。
我需要用字节对整数进行算术运算。
int a = 0x0100;
byte b = (byte)0xff;
int c = a | b;
我希望 c 为 0x100 | 0xff = 0x1ff = 511
。
但它是 0xffffffff = -1
为什么?
b
是 -1
。
当您执行 a | b
时,b
被提升为仍然是 -1
.
15.22.1. Integer Bitwise Operators &, ^, and |
When both operands of an operator &, ^, or |
are of a type that is convertible (§5.1.8) to a primitive integral type,
binary numeric promotion is first performed on the operands (§5.6.2).
因此,a | b
的计算结果如同 a | -1
。
final int a = 0x0100;
final int b = 0xFF;
final int c = a | b;
我不确定你到底想做什么,但是。
How could I accomplish adding 8 bits to the end of a int value in simple steps?
int appendDummyOnes(final int value, final int size) {
return (value << size) | (-1 >>> (Integer.SIZE - size));
}
int remarkDummyOnes(final int value, final int size) {
return value | (-1 >>> (Integer.SIZE - size));
}
这个有效:
int c = a | (b & 0xff);
在您的代码中
int c = a | b;
byte b 扩展为 int 并保留值(-1 表示此值在 signed int 中)。 这个值在int中是0xFFffFFff,所以在0x0100 |之后0xFFffFFff 你得到了 0xFFffFFff
如 Jin Kwon 的回答所述 - 在当前情况下您应该使用整数。
(b & 0xFF)
之外): Java 8 添加了一些处理无符号值的便捷方法。所以你可以简单地做
int c = a | Byte.toUnsignedInt(b);
我将此用于您的代码。您的代码变得疯狂的原因是:
You were using integer (int) data type which is of 1 byte (8 bit) but you were processing data of 2 bytes (16 bits). In such cases, the MSB (8th bit) is taken as sign bit which is 0 for (-ve) and 1 for(+ve).
事实上,OR 运算符并没有发疯,这是您的代码。您可以使用类似于下面的实现来使您的代码运行良好:
import java.io.*;
import java.util.*;
class Lesson7{
public static void main(String args[]){
int a = 0x01;
byte b = (byte)0x00;
int c = a | b;
System.out.println(c);
}
}
我测试过这个:
int a = 0x100;
int b = 0xff;
int c = a|b;
System.out.println(c);