繁体   English   中英

java 中基本类型的转换规则

[英]Casting rules for primitive types in java

在 java 中,

有整数类型( char / short / int / long / byte

有浮动类型( float / double

有 boolean 类型( boolean ),不是整数类型,不像 C 语言。

问题:

  1. 是否有一个通用的铸造规则(根据 JLS),可以将哪种类型转换为另一种类型? 出于常识,我知道,不允许将整数和浮点类型转换为boolean

  2. 请帮我理解下面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

The JLS lists

19 specific conversions on primitive types are called the widening primitive conversions:

  • byte to short, int, long, float, or double
  • short to int, long, float, or double
  • char to int, long, float, or double
  • int to long, float, or double
  • long to float or double
  • float to double

Note the missing conversions from byte and short to char, even though char is two bytes long.

Everything else needs an explicit cast. Narrowing is a little more complex:

  • double to float 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 to int by rounding towards zero. Then the resulting int is converted to the target type using integer conversion.

Examples:

int doubleToInt = (int)aDoubleValue; 

yields Integer.MAX_VALUE as per rounding rules.

byte doubleToByte = (byte)aDoubleValue; 

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;

same again: converts to int, yielding Integer.MAX_VALUE. 0x7fffffff to short yields 0xffff, i.e. -1.

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.

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.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM