java java中原始类型的转换规则

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30776256/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:38:29  来源:igfitidea点击:

Casting rules for primitive types in java

javacasting

提问by overexchange

In java,

在Java中,

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

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

There are floating types(float/double)

有浮动类型( float/ double)

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

boolean与C语言不同,有boolean type( ),不是整型。

Question 1)

问题 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 booleanis not allowed

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

Question 2)

问题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?

回答by dhke

The JLS lists

JLS列表

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

原始类型的 19 种特定转换称为扩展原始类型转换:

  • 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
  • 字节到 short、int、long、float 或 double
  • 短到 int、long、float 或 double
  • char 到 int、long、float 或 double
  • int 到 long、float 或 double
  • long 浮动或加倍
  • 浮动到两倍

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

其他一切都需要明确的演员表。缩小范围有点复杂:

  • doubleto floatuses 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 intby rounding towards zero. Then the resulting intis converted to the target type using integer conversion.
  • doublefloat使用标准的IEEE 754舍入。
  • 整数值的最高有效位被剥离到目标类型的可用宽度。这可能会导致出现符号位,例如(byte)0xfff == (byte)-1
  • 如果源类型是浮点类型而目标类型是long,则通过向零舍入来转换值。
  • 如果源类型是浮点类型而目标类型是整数但不是long,则首先int通过向零舍入来转换该值。然后int使用整数转换将结果转换为目标类型。

Examples:

例子:

int doubleToInt = (int)aDoubleValue; 

yields Integer.MAX_VALUEas per rounding rules.

产率Integer.MAX_VALUE作为每四舍五入规则。

byte doubleToByte = (byte)aDoubleValue; 

first converts to int, yielding Integer.MAX_VALUEand then converts that to byte. Integer.MAX_VALUEis 0x7fffffff, hence the byte value 0xffwhich is -1.

首先转换为int,产生Integer.MAX_VALUE,然后将其转换为byteInteger.MAX_VALUE0x7fffffff,因此字节值0xff-1

short doubleToShort = (short)aDoubleValue;

same again: converts to int, yielding Integer.MAX_VALUE. 0x7fffffffto shortyields 0xffff, i.e. -1.

再次相同:转换为int,产生Integer.MAX_VALUE0x7fffffffshort产量0xffff,即-1

The tricky thing is actually the to-charconversion. charis a single, 16-bit unicode character, hence char doubleToChar = (char)aDoubleValuegives you '\uffff'by the now familiar rules.

棘手的事情实际上是 to-char转换。char是一个单一的 16 位 unicode 字符,因此按照现在熟悉的规则char doubleToChar = (char)aDoubleValue为您提供'\uffff'

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.

整数语义可能继承自 C。至少浮点到整数缩小操作的第一步也是您所期望的。第二个缩小步骤,从 double/float 到 short、byte 和 char 似乎有点令人惊讶,但如果你真的将 float 转换为 short,你应该仔细检查一下你知道你在做什么。