java 分转元,java中基元类型的转换规则

In java,

There are integral types(char/short/int/long/byte)

There are floating types(float/double)

There is boolean type(boolean), not integral type, unlike C language.

Question 1)

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

Question 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?

解决方案

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

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.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值