【问题标题】:casting between short,int,long,double,float in Java在 Java 中的 short、int、long、double、float 之间进行转换
【发布时间】:2012-05-09 13:13:14
【问题描述】:

据我了解,当您使用 Java 中的算术运算(例如 double + int)在其中两种类型之间进行转换时,结果将是较大的类型(在此示例中,结果将是 double)。当你对两种大小相同的类型进行算术运算时会发生什么? int + float 和 long + double 会给出什么?因为 int 和 float 分别是 4 个字节,而 long 和 double 是 8 个字节。

【问题讨论】:

    标签: java types casting int double


    【解决方案1】:

    这都是由 JLS 中的二进制数字提升规则指定的。来自http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2

    当一个运算符将二进制数字提升应用于一对 操作数,每个操作数必须表示一个可转换为 数字类型,按顺序适用以下规则:

    1. 如果任何操作数是引用类型,则对其进行拆箱 转换(第 5.1.8 节)。

    2. 加宽基元转换(第 5.1.2 节)用于转换或 两个操作数均由以下规则指定:

      • 如果任一操作数为 double 类型,则将另一个转换为 double。

      • 否则,如果任一操作数为浮点类型,则转换另一个 浮动。

      • 否则,如果任一操作数为 long 类型,则转换另一个 太长了。

      • 否则,两个操作数都转换为 int 类型。

    类型转换后,如果有的话,值集转换(§5.1.13)是 应用于每个操作数。

    对某些运算符的操作数执行二进制数字提升:

    • 乘法运算符 *、/ 和 %(第 15.17 节)

    • 数字类型 + 和 - 的加法和减法运算符 (§15.18.2)

    • 数值比较运算符 和 >=(第 15.20.1 节)

    • 数值相等运算符 == 和 != (§15.21.1)

    • 整数位运算符 &、^ 和 | (§15.22.1)

    • 在某些情况下,条件运算符 ? : (§15.25)

    (“值集转换”是关于浮点表示之间的映射。)

    【讨论】:

      【解决方案2】:

      int + float 将给您float(请注意,您必须将结果转换为float,因为默认使用double)。 long + double 会给你double

      【讨论】:

        【解决方案3】:

        仍然会返回可以保存完整值的"bigger" 类型。在您的具体问题中

        如果你在 int 和 float 之间加上 +,返回值将是 float 而 long + double 返回一个 double,

        【讨论】:

          【解决方案4】:

          加法运算符+- 的行为由JLS 的15.18.2. Additive Operators (+ and -) for Numeric Types 定义。它声明它首先执行二进制数字提升:

          对操作数执行二进制数字提升。

          这又由5.6.2. Binary Numeric Promotion 定义。实质上,对于原语:

          • 如果任一操作数为 double 类型,则另一个将转换为 double。
          • 否则,如果任一操作数为浮点类型,则将另一个转换为浮点类型。
          • 否则,如果任一操作数为 long 类型,则将另一个转换为 long。
          • 否则,两个操作数都将转换为 int 类型。

          【讨论】:

            【解决方案5】:

            有两个关于类型转换的有趣常见问题解答可以在以下位置找到:http://www.programmersheaven.com/2/FAQ-JAVA-Type-Conversion-Casting

            http://myhowto.org/java/60-understanding-the-primitive-numeric-type-conversions-in-java/

            回答你关于大小相同的两种类型的问题,返回值是精度最大的类型。

            试试下面的代码:

            public static void main(String[] args) {
                int i=1;
                float f=2.5f;
                long l=10;
                double d=3.74;
                System.out.println(i+f);
                System.out.println(f+i);
                System.out.println(l+d);
                System.out.println(d+l);
            }
            

            您会看到结果是 3.5 和 13.74,分别是浮点数和双精度数(在 Netbeans 6.9 和 java 1.6 中测试)。

            【讨论】:

              【解决方案6】:

              这个“促销”的一个陷阱是 long + float 将“扩大”到使用浮动。

              例如

              System.out.println(1111111111111111111L + 0.0f);
              System.out.println(1111111111111111111L + 0.0);
              

              打印

              1.11111113E18
              1.11111111111111117E18
              

              在处理 long 和 float 时,您可能无法获得更宽的类型,并且可能会损失比您预期的更多的精度。

              【讨论】:

              • 恕我直言,Java 应该禁止与许多运算符的类型组合,在大多数情况下目标类型明确为 float 时,允许从 doublefloat 的隐式转换,因为这样的转换几乎总是产生预期的行为,并且不允许从 floatdouble 的隐式转换,因为这样的转换通常是错误的(例如,double OneTenth=1.0f/10.0f; 应该在恕我直言,但没有)。如果生成的 float 不能直接与其他类型交互,我不介意从 longfloat 的隐式转换。
              • @supercat 我同意,但是 double 的其他方式具有更高的精度,这就是为什么从浮点数转换为双精度数是可以的。 (您可以毫无损失地转换回来)如果您将 double 转换为 float 并再次转换回来,您可能会失去精度,这就是它不安全的原因。一般来说,我会避免使用 float,因为它在 99% 的情况下都没有用。
              • 隐式类型转换可以(而且恕我直言应该)满足许多公理,以尽量减少“惊讶”;我刚刚在supercatnet.blogspot.com/2013/09/… 写了一篇博文,希望得到您的反馈。对我来说,最重要的一点是,如果tT 对某个抽象量x 的最佳表示,并且存在从TU 的隐式转换,那么(U)t 应该是 U 对同一 x 的最佳表示之一。另一个是 (U)t==t 不应该为类型和值的任何组合返回 false。要么...
              • @supercat 我同意。 (double) 0.1f == 0.1f 是真的。 (float) 0.1 == 0.1 是假的。
              • 您想在我的博客或聊天中讨论这个问题吗?我想要你对我在那里写的内容的反馈。至于您的情况,如果我正在编写规则并且无法使 long a=b*c; 等同于 long a=(long)b*c; 我会让该语言需要对 int 进行类型转换(例如 long a=(int)(b*c); 通过例如带有属性禁止的标记运算符它的返回值在程序员可能期望long的地方使用。
              猜你喜欢
              • 2013-09-25
              • 2016-11-15
              • 2014-02-05
              • 1970-01-01
              • 2014-05-11
              • 1970-01-01
              • 1970-01-01
              • 2011-07-17
              • 1970-01-01
              相关资源
              最近更新 更多