java中原始类型的转换规则 [英] Casting rules for primitive types in java
问题描述
在Java中,
有整数类型(char
/short
/int
/long
/byte代码>)
There are integral types(char
/short
/int
/long
/byte
)
有浮动类型(float
/double
)
有布尔类型(boolean
),不是整型,不像C语言.
There is boolean type(boolean
), not integral type, unlike C language.
问题 1)
是否有用于转换的通用规则(根据 JLS),可以将哪种类型转换为另一种类型?出于常识,我知道,整型和浮点型转换为 boolean
是不允许的
Is there a generic rule for casting(as per JLS) that talks, which type can be converted to another type? Out of common sense, I know that, integral and floating types casting to boolean
is not allowed
问题 2)
请帮助我理解以下输出的原因:
Please help me understand the reasons for below output:
/*
* Casting rules for primitive types
*/
double aDoubleValue = 30000000000000000000.123438934;
int doubleToInt = (int)aDoubleValue; //stores max value 2147483647, makes sense!!
byte doubleToByte = (byte)aDoubleValue; //stores -1, why not 127?
short doubleToShort = (short)aDoubleValue; // stores -1, why not 32767?
long doubleToLong = (long)aDoubleValue; // stores 9223372036854775807, makes sense!!
float doubleToFloat = (float)aDoubleValue; // stores 3.0E19, 3.0 x 10^19 max value of float
char doubleToChar = (char)aDoubleValue; // what does this store?
推荐答案
JLS 列表
原始类型的 19 种特定转换称为扩展原始类型转换:
19 specific conversions on primitive types are called the widening primitive conversions:
- byte 到 short、int、long、float 或 double
- short 到 int、long、float 或 double
- char 到 int、long、float 或 double
- int 到 long、float 或 double
- 长时间浮动或加倍
- 浮动到两倍
double
到float
使用标准 IEEE 754 舍入.- 整数值的最高有效位被剥离到目标类型的可用宽度.这可能会导致出现符号位,例如
(byte)0xfff == (byte)-1
; - 如果源类型是浮点类型而目标类型是
long
,则通过向零舍入来转换值. - 如果源类型是浮点型并且目标类型是整数但不是
long
,则该值首先通过向零舍入来转换为int
.然后使用整数转换将结果int
转换为目标类型. double
tofloat
uses standard IEEE 754 rounding.- integer values have their most significant bits stripped to the available width of the target type. This may result in a sign bit appearing, e.g.
(byte)0xfff == (byte)-1
; - If the source type is floating point and the target type is
long
, the value is converted by rounding towards zero. - If the source type is floating point and the target type is integral but not
long
, the value is first converted toint
by rounding towards zero. Then the resultingint
is converted to the target type using integer conversion.
其他一切都需要显式转换.缩小是稍微复杂一点:
Everything else needs an explicit cast. Narrowing is a little more complex:
示例:
int doubleToInt = (int)aDoubleValue;
根据舍入规则产生 Integer.MAX_VALUE
.
byte doubleToByte = (byte)aDoubleValue;
首先转换为int
,产生Integer.MAX_VALUE
,然后将其转换为byte
.Integer.MAX_VALUE
是 0x7fffffff
,因此字节值 0xff
是 -1
.
first converts to int
, yielding Integer.MAX_VALUE
and then converts that to byte
. Integer.MAX_VALUE
is 0x7fffffff
, hence the byte value 0xff
which is -1
.
short doubleToShort = (short)aDoubleValue;
再次相同:转换为 int
,产生 Integer.MAX_VALUE
.0x7ffffff
到 short
产生 0xffff
,即 -1
.
same again: converts to int
, yielding Integer.MAX_VALUE
. 0x7fffffff
to short
yields 0xffff
, i.e. -1
.
棘手的事情实际上是 to-char
转换.char
是一个单一的 16 位 unicode 字符,因此 char doubleToChar = (char)aDoubleValue
通过现在熟悉的方式为您提供 'uffff'
规则.
The tricky thing is actually the to-char
conversion. char
is a single, 16-bit unicode character, hence char doubleToChar = (char)aDoubleValue
gives you 'uffff'
by the now familiar rules.
可以看出浮点和整数缩小操作之间存在差异.浮点运算执行实际舍入,而整数运算执行按位钳位.
As can be seen there is a difference between floating point and integer narrowing operations. The floating point operations do actual rounding, while the integer operations perform bitwise clamping.
整数语义可能继承自 C.至少浮点到整数缩小操作的第一步也是您所期望的.第二个缩小步骤,从 double/float 到 short、byte 和 char 可能看起来有点令人惊讶,但如果你真的将 float 转换为 short,你应该仔细检查一下你知道你在做什么.
The integer semantics are probably inherited from C. At least the first step of the float-to-integral narrowing ops are also what you expected. The second narrowing steps, from double/float to short, byte and char may seem a little surprising, but if you really cast float to short, you should probably double check that you know what you are doing anyway.
这篇关于java中原始类型的转换规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!