6

有一些事情让我感到困惑,我没有找到太多关于 VM 规格的信息。这有点晦涩难懂,如果有人可以解释一下,那就太好了。

这几行代码......

double myTest = Double.MAX_VALUE;

System.out.println("1. float: " + (float)myTest);
System.out.println("2. int: " + (int)myTest);
System.out.println("3. short: " + (short)myTest);
System.out.println("4. byte: " + (byte)myTest);

.....产生这个输出:

  1. 浮动:无穷大
  2. 诠释:2147483647
  3. 短:-1
  4. 字节:-1

byte,short并且int是 8, 16, 32 位,带二进制补码。float并且double是 32 位和 64 位 IEEE 754(请参见此处)。

据我了解,a 的最大值double意味着尾数的所有位(52 位)都切换为 1。因此,转换为短或字节返回 -1 并不(非常)令人惊讶,即所有位都切换到1.演员似乎保留了'尾巴' double,使其适合 8 位byte或 16 位short

令我惊讶的是演员int阵容,在较小程度上,演员阵容float。如何获得“2. int: 2147483647”,即 0x7FFFFFFF,short 和字节 3. 和 4. 为 -1 时的最大值?

演员float阵容也很奇怪。如果保留 'tail' 的 32 位myTest,那么它不应该生成一个NaN?

4

1 回答 1

6

JLS 在5.1.3 Narrowing Primitive Conversion部分中详细说明了规则。规则取决于目标类型。

float

从 double 到 float 的窄化原语转换受 IEEE 754 舍入规则 (§4.2.4) 的约束。这种转换可能会丢失精度,但也会丢失范围,从而导致非零双精度浮点数为零和有限双精度浮点数无穷大。双精度 NaN 转换为浮点 NaN,双无穷大转换为同符号浮点无穷大。

intlong

以下两种情况之一必须为真:

  • ...
  • 该值必须太大(一个大的正值或正无穷大),并且第一步的结果是 int 或 long 类型的最大可表示值。

byte,charshort:

如果目标类型是byte,charshort,则转换它两步。首先,将double转换long为如上所述。然后,将long转换为最终类型,如下所示:

有符号整数到整数类型 T 的窄化转换只会丢弃除 n 个最低位之外的所有位,其中 n 是用于表示类型 T 的位数。此外,可能会丢失有关数值大小的信息,这可能会导致结果值的符号与输入值的符号不同。

于 2012-05-07T07:45:43.847 回答