Java中整数如何转换为字节?

28

我知道Java不允许无符号类型,所以我想知道它是如何将整数转换为字节的。假设我有一个值为255的整数a,并将该整数转换为字节。那么在字节中表示的值是11111111吗?换句话说,该值被视为有符号8位整数处理,还是直接复制整数的最后8位?

8个回答

31
这被称为缩小原始转换。根据规范:
将有符号整数缩小转换为整型T只是舍弃除类型T所用的位数之外的所有低位,其中n 是表示类型T 所使用的位数。除了可能丢失有关数字值大小的信息之外,这还可能导致生成的值的符号与输入值的符号不同。
因此,它是您列出的第二个选项(直接复制最后8位)。
我不确定您是否了解有符号整数值的表示方式,因此为了安全起见,我指出字节值1111 1111在二进制补码系统中等于-1(Java使用该系统)。

是的,我知道补码。那么,为了澄清一下,如果我有一个值为-1的长整型,并将其强制转换为整型,结果将是65535吗?顺便感谢您快速而详细的回复。 - LandonSchropp
1
@helixed:不,它也会是-1,因为它也是全1。任何在较小类型范围内的内容都将被转换为相应的值。 - Michael Myers
哦,我明白了。由于使用了二进制补码,任何在较小类型范围内的负值都会被填充为1(二进制),因此结果将始终保留其符号。再次感谢。 - LandonSchropp
@helixed:是的,没错。一旦超出较小类型的范围,它就相当于溢出或下溢。 - Michael Myers

6
int i = 255;

byte b = (byte)i;

因此,十六进制中be的值为0xFF,但十进制值为-1。

int i = 0xff00;

byte b = (byte)i;

现在b的值为0x00。这表明Java取整数的最后一个字节,即最后8位,但这是带符号的。

我可以搜索什么来了解大括号类型转换技巧?“(byte)i” - Roman Voronov

4

或者它只是直接复制整数的最后8位

是的,这就是此转换的工作方式。


2
字节是8位。8位可以表示256个数字。(2的8次方=256)
现在第一位用于表示符号。[如果是正数,则第一位为0,如果是负数,则第一位为1]
假设您要将整数1099转换为字节。只需将1099除以256即可。余数就是您的int的字节表示形式。
示例
1099/256 => 余数= 75
-1099/256 =>余数=-75
2049/256 => 余数= 1
为什么?看看这张图片 http://i.stack.imgur.com/FYwqr.png

按照您的方法,整数值130会得到一个超出字节范围的余数130 - undefined

2
以下代码片段将一个 int 强制转换为 byte。如果整数的值大于 byte 的范围,则会对其进行模运算(即整数除法的余数)并缩小至 byte 的范围内。
int a;
byte b;
// …
b = (byte) a;

1
根据我的理解,您的意思是:

Integer i=new Integer(2);
byte b=i;   //will not work 

final int i=2;
byte b=i;   //fine 

最后。
Byte b=new Byte(2);
int a=b;   //fine

1

关于所说的一点想法:在将整数转换为字节时,始终使用0xFF(对于整数)进行掩码处理。(假设myInt的值从0到255)。

例如:

char myByte = (char)(myInt & 0xFF);

为什么?如果myInt大于255,只需将其强制转换为byte会返回一个负值(2的补码),这是您不想要的。

在Java中,char类型占用两个字节的空间。 - Paul
3
在Java中,char是16位。如果你将例子改成byte也不行,可能仍会产生负值。你可以使用0x7F掩码,但这样会导致负值无法正确转换。确保不会遇到问题的好方法可能是 assert -128 <= myInt && myInt <= 127; - Philippe Beaudoin
@Philippe,谢谢。我工作到很晚,所以写得太快了,但是,在Java中short有多大? - Buhake Sindi
1
short 是有符号的两字节类型,而 char 是无符号的两字节类型。 - Michael Myers
我理解你想说的话,这是一般情况下的好建议。在我的具体情况中,我已经知道 int 中的值小于 255。 - LandonSchropp

0
for (int i=0; i <= 255; i++) {
    byte b = (byte) i;    // cast int values 0 to 255 to corresponding byte values 
    int neg = b;     // neg will take on values 0..127, -128, -127, ..., -1
    int pos = (int) (b & 0xFF);  // pos will take on values 0..255
}

当一个字节包含大于127的值时(即值0x80到0xFF),将其转换为int会导致字节值的高位比特(即0x80比特)进行符号扩展。要删除“额外”的一位,使用x& 0xFF;这将强制高于0x80(即0x100、0x200、0x400等)的位为零,但保留低8位不变。

您也可以编写以下内容;它们都是等效的: int pos = ((int) b) & 0xFF; //先将b转换为int,然后剥离高位 int pos = b & 0xFF; //作为int算术完成--不需要转换

在执行算术运算时,Java会自动将大小(以位数计)小于int的整数类型“提升”为int值。这样做是为了提供比较确定的结果(与C语言相比,其规范性较低)。

您可能想看看有关转换“短”的问题的此问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接