我是Java的初学者。 我遇到了一个叫做类型铸造的概念。我有以下片段-
class Demo
{
byte b;
int a=257;
double d= 323.142
b=(byte)a;
System.out.println(b);
b=(byte)d;
System.out.println(b);
}
代码的输出1
67
谁能解释一下输出。
提前感谢!
byte
类型以 8 位编码,因此其值介于 -128 和 127 之间。在您的情况下,按 byte
进行转换与计算模数并舍入为int
相同。尝试以下代码,输出相同:
int a = 257;
double d = 323.142;
System.out.println(a % 128);
System.out.println((int) d % 128);
在这两种情况下,您都在进行缩小转换范围,这可能会导致信息丢失。
- 将 int 转换为 字节
int 转换为字节。因此,仅保留 int 的最低(右(字节。因此,结果以二进制形式00000001,即 1。
- 将双精度转换为字节
此转换更为复杂。
- 在第一步中,323.142 从 double 转换为 int,因此变为 323。
第二步与第一次转换相同:
323 是二进制中的 00000000000000000 00000001 01000011。将 323 转换为字节会保留最低(右(字节,即 67。
以下是JLS对此转换的评价:
将浮点数缩小到整数类型的转换 T 需要两个步骤:
在第一步中,浮点数转换为长整型(如果 T 为长(或 int(如果 T 为字节、短整型、字符或 int,如下所示:
- 否则,如果浮点
如果浮点数为 NaN (§4.2.3(,则转换的第一步的结果是 int 或长整型 0。
数不是无穷大,则浮点值将舍入为整数值 V,舍入 使用 IEEE 754 舍入到零模式 (§4.2.3( 接近零。然后那里 有两种情况:
一个。如果 T 很长,并且这个整数值可以表示为长整型,那么第一步的结果就是长整型值 V。
b. 否则,如果此整数值可以表示为 int,则第一步的结果是 int 值 V。
否则,必须满足以下两种情况之一:
一个。该值必须太小(大量级或负无穷大的负值(,第一步的结果是 int 或 long 类型的最小可表示值。
二.该值必须太大(大量级或正无穷大的正值(,第一步的结果是 int 或 long 类型的最大可表示值。
第二步:
如果 T 为 int 或 long,则转换的结果是第一步的结果。
如果 T 是字节、字符或短整型,则转换结果是缩小到结果类型 T (§5.1.3( 的结果 第一步。
byte b;
int a=257;
double d= 323.142
b=(byte)a; // 257-256=1
System.out.println(b); // now b is 1
b=(byte)d; // 323.142-256=67
System.out.println(b); // now b is 67
byte 数据类型是一个 8 位有符号二进制的补码整数(这在第二种情况下很重要,为什么67.142
变成 67
(。 Java
中的字节是有符号的,因此它具有-2^7
到2^7-1
的范围 - 即-128
到127
。由于257
高于127
,你最终会绕到257-256=
1。也就是说256
相加或减,直到它落入范围。同样的情况也发生在第二种情况下。
可以存储在-128 to 127
范围之间,这意味着1字节(8位(。257
的二进制值在转换为字节后100000001
,这意味着 8 位(从 LSB
到 MSB
(,它将获得 00000001
的值,这只不过是1
。在这里,您显式转换类型,以便在将较高的数据类型转换为较低的数据类型时发生数据丢失。后一个也是如此。希望这对您有所帮助。
的十六进制表示形式
- (257( = 0x101
- (323( = 0x143
byte
仅存储一个字节的数据,正如您在上面的十六进制表示中看到的突出显示的部分:-
对于 257 b = 0x01 = 1
,对于 323.14 的整数部分b = 0x43 = 67
注意:- 在 Java 中,double
使用 52 位尾数,因此我们可以表示一个 32 位整数而不会丢失数据。
因为 257 = 100000001b但是当你把它转换为字节时,你只得到这个数字的 8 位:00000001b = 1