将双精度类型转换为另一个数字类型 [英] Casting a double to another numeric type
问题描述
有些令人困惑的事情,我没有找到有关VM规格的太多信息。 b
这几行代码.....
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);
...产生以下输出:
- 浮动:Infinity
- int:2147483647
- short:-1
- byte:-1
byte
, short
和 int
是8、16、32位,带有二进制补码。 float
和 double
是32位和64位IEEE 754(请参见此处)。
据我了解, double
的最大值表示螳螂的所有位(52位)切换为1。因此,将short或byte强制转换返回-1(即将所有位都转换为1)并不(非常)令人惊讶。似乎强制转换保留了 double的'tail'。
,使其适合8位 byte
或16位 short
。
让我惊讶的是强制转换为 int
,在较小程度上,强制转换为 float
。
如何获得 2. int:2147483647,即0x7FFFFFFF,即short和byte 3和4.为-1时的最大值是-1吗?
对 float
的转换也很奇怪。如果保留了 myTest
的尾部的32位,那么它不应该生成 NaN
吗?
JLS阐明了 5.1.3缩小基元转换。规则取决于目标类型。
float
:
从double到float的原始缩元转换受IEEE 754舍入规则(第4.2.4节)支配。这种转换可能会失去精度,但也会失去范围,导致非零双精度浮点为零,而有限双精度浮点为无穷大。将double NaN转换为float NaN,将double infinity转换为相同符号的float infinity。
int
和 long
:
以下两种情况之一必须为真:
- ...
- 该值必须太大(正值较大或正无穷大),并且第一步的结果是int或long类型的最大可表示值。
byte
, char
和 short
:
如果目标类型是 byte
, char
或 short
,转换过程分为两步。首先,将 double
转换为 long
,如上所述。然后,将 long
转换为最终类型,如下所示:
变窄将有符号整数转换为整数类型T会简单地丢弃除n个最低阶位以外的所有位,其中n是用于表示类型T的位数。除了可能丢失有关数值幅度的信息外,这可能导致结果值的符号与输入值的符号不同。
there is something puzzling me and I did not find much information on the VM specs. It's a bit obscure and that'd be nice if someone could explain me.
These few lines of code.....
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);
..... produce this output:
- float: Infinity
- int: 2147483647
- short: -1
- byte: -1
byte
, short
and int
are 8, 16, 32 bit with two's complement. float
and double
are 32 and 64 bit IEEE 754 (see here).
From my understanding, the max value of a double
implies that all the bits of the mantisse (52 bits) are switched to 1. Therefore it's not (very) surprising that a cast to short or to byte returns -1 i.e all bits are switched to 1. It seems that the cast keeps the 'tail' of the double
so that it fits into 8 bit byte
or 16 bit short
.
What surprises me is the cast to int
and, to a lesser extent, the cast to float
.
How is it possible to get "2. int: 2147483647" which is 0x7FFFFFFF, the maximal value while short and byte 3. and 4. are -1 ?
The cast to float
is also weird. If the 32 bits at the 'tail' of myTest
were kept, then shouldn't it generate a NaN
?
JLS spells out the rules in section 5.1.3 Narrowing Primitive Conversion. The rules depend on the target type.
float
:
A narrowing primitive conversion from double to float is governed by the IEEE 754 rounding rules (§4.2.4). This conversion can lose precision, but also lose range, resulting in a float zero from a nonzero double and a float infinity from a finite double. A double NaN is converted to a float NaN and a double infinity is converted to the same-signed float infinity.
int
and long
:
one of the following two cases must be true:
- ...
- The value must be too large (a positive value of large magnitude or positive infinity), and the result of the first step is the largest representable value of type int or long.
byte
, char
and short
:
If the target type is byte
, char
or short
, the conversion it two-step. First, the double
is converted to long
as explained above. Then, the long
is converted to the final type as follows:
A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.
这篇关于将双精度类型转换为另一个数字类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!