【发布时间】:2011-01-28 08:18:52
【问题描述】:
我知道 Java 不允许无符号类型,所以我想知道它是如何将整数转换为字节的。假设我有一个值为 255 的整数 a 并将整数转换为一个字节。该值是否以字节 11111111 表示?换句话说,该值是更多地被视为一个有符号的 8 位整数,还是直接复制整数的最后 8 位?
【问题讨论】:
我知道 Java 不允许无符号类型,所以我想知道它是如何将整数转换为字节的。假设我有一个值为 255 的整数 a 并将整数转换为一个字节。该值是否以字节 11111111 表示?换句话说,该值是更多地被视为一个有符号的 8 位整数,还是直接复制整数的最后 8 位?
【问题讨论】:
以下片段将 int 转换为 byte。如果整数的值大于一个字节的范围,它将以模(整数除以的余数)字节的范围缩小。
int a;
byte b;
// …
b = (byte) a;
【讨论】:
根据我的理解,你的意思是
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
【讨论】:
字节为 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
【讨论】:
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 相比,C 的规范限制较少)。
【讨论】:
只是对所说内容的想法:在转换为具有 0xFF 的字节时(对于整数),请始终屏蔽您的整数。 (假设 myInt 被赋值为 0 到 255)。
例如
char myByte = (char)(myInt & 0xFF);
为什么?如果 myInt 大于 255,则仅类型转换为 byte 会返回您不想要的负值(2 的补码)。
【讨论】:
char 在 java 中是 16 位。如果您将示例更改为byte,它也不起作用,仍然可能产生负值。您可以使用 0x7F 进行屏蔽,但是负值将无法正确转换。确保您不会遇到问题的好方法可能是assert -128 <= myInt && myInt <= 127;
short 在 java 中有多大?
short 是有符号的两字节类型,而char 是无符号的两字节类型。
这称为narrowing primitive conversion。根据规范:
有符号整数到整数类型的窄化转换T 只会丢弃除n 个最低位之外的所有位,其中n 是用于表示类型 T 的位数。除了可能丢失有关数值大小的信息外,这还可能导致结果值的符号与输入值的符号不同。
所以这是您列出的第二个选项(直接复制最后 8 位)。
我不确定你是否知道有符号整数值是如何表示的,所以为了安全起见,我会指出 two's complement 系统中的字节值 1111 1111 等于 -1 (Java 使用的)。
【讨论】:
int i = 255;
byte b = (byte)i;
所以十六进制的值为0xFF,但十进制值为-1。
int i = 0xff00;
byte b = (byte)i;
b 的值现在是 0x00。这表明 java 取整数的最后一个字节。 IE。最后 8 位,但这是有符号的。
【讨论】:
还是直接复制最后一个 8位整数
是的,这就是这种铸造的工作方式
【讨论】: