字节是不是签名的两个补码?

时间:2012-05-03 11:52:26

标签: java primitive

鉴于byte,short和int是有符号的,为什么Java中的byte和short不能得到通常的signed two's complement处理?例如,0xff对于byte是非法的。

这已在here之前讨论过,但我无法找到原因。

5 个答案:

答案 0 :(得分:4)

如果您查看用于在已签名字节中存储-1的实际内存,那么您将看到它是0xff。但是,在语言本身,而不是二进制表示,0xff只是超出一个字节的范围。 -1的二进制表示确实会使用两个补码,但您可以屏蔽该实现细节。

语言设计人员只是采取这样的立场,即尝试将255存储在只能保存-128到127的数据类型中应被视为错误。

您在评论中询问Java允许:

int i = 0xffffffff;

文字0xffffffffint字面值,使用二进制补码进行解释。您不能对字节执行任何类似操作的原因是该语言不提供用于指定文字属于byte类型或short类型的语法。

我不知道为什么决定不提供更多文字类型。我希望它是出于简单的原因而制作的。该语言的目标之一是避免不必要的复杂性。

答案 1 :(得分:4)

你可以写

int i = 0xFFFFFFFF;

但你不能写

byte b = 0xFF;

因为0xFF是int值而不是byte所以它等于255.没有办法定义字节或短文字,所以你必须强制转换它。

BTW你可以做到

byte b = 0;
b += 0xFF;
b ^= 0xFF;

甚至

byte b = 30;
b *= 1.75; // b = 52.

答案 2 :(得分:1)

这是合法的,但你需要明确地将其强制转换为字节,即(字节)0xff,因为它超出了范围。

答案 3 :(得分:1)

您可以逐字设置一个字节,但令人惊讶的是,您必须使用更多数字:

byte bad = 0xff; // doesn't work
byte b = 0xffffffff; // fine

逻辑是,0xff隐式为0x000000ff,超出了一个字节的范围。 (255)

这不是你想到的第一个想法,但它有一些逻辑。数字越长,数字越小(绝对值越小)。

byte b = 0xffffffff; // -1 
byte c = 0xffffff81; // -127 
byte c = 0xffffff80; // -128

答案 4 :(得分:0)

byte的可能值范围为-128到127.

可以让超出范围的值分配给变量,然后静默地丢弃溢出,但这样做比混淆更令人困惑。

然后我们会:

byte b = 128;
if (b < 0) {
  // yes, the value magically changed from 128 to -128...
}

在大多数情况下,最好让编译器告诉你值超出范围而不是“修复”它。