在这种情况下,为什么Java将double转换为float类型?

时间:2019-03-03 02:32:11

标签: java eclipse

今天,我定义了两个浮点变量 f1 f2 。然后我执行加法运算“ +”,并将其分配给浮点变量 f

float f1 = 0.5048076923076923F;
float f2 = 0.5048076923076923F;
float f = f1 + f2;

这是输出:
enter image description here

根据此图片,算术运算中的所有浮点值( float double +,-,*,/ )将转换为 double 类型: 图片来源:http://www.mathcs.emory.edu/~cheung/Courses/170/Syllabus/04/mixed.html
image

我发现了一个相同的问题,但没有解释原因。为什么月食没有任何提示?是 “ f1 + f2” 的值是浮点型的原因吗?并且,为什么Java会如上图所示自动将double转换为float类型? picture source: https://www.homeandlearn.co.uk/java/short_float_variables.html

PS:英语不是我的母语,如果这个问题有语法问题,请原谅我。谢谢。 :)

4 个答案:

答案 0 :(得分:4)

您的老师是不正确的,请推荐他到section 5.6.2 of the Java Language Specification,其中指出:

  
      
  • 通行基元转换(第5.1.2节)适用于转换以下规则指定的一个或两个操作数:

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

    •   
    • 否则,如果其中一个操作数的类型为float,则另一个将转换为float。

    •   
    • 否则,如果其中一个操作数的类型为long,则另一个将转换为long。

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

    •   
  •   

如您所见,浮点数仅会转换为双精度,如果另一个操作数为双精度,则不会在所有情况下都转换为双精度模式。

也就是说,两个浮点数之和是一个浮点数,但是一个浮点数和一个double的和是double。

PS:不,Java绝不会将double转换为float,除非您明确要求,例如:

float f = (float) Math.PI;

答案 1 :(得分:4)

您似乎在说以下内容已转换为float

float f1 = 0.5048076923076923F;
float f2 = 0.5048076923076923F;
float f = f1 + f2;

实际上,没有转换。这些值都是float

尤其是,文字0.5048076923076923Ffloat。尾随F使其成为float。如果您要使用双精度字面量,请不要使用F或将其替换为D

当您的老师说“所有浮点值都转换为double”时,他是错误的。 JLS表示(实际上)当另一个操作数是double 时,数字基元操作数将转换为double 。如果两个操作数均为float,则将使用单精度浮点算法执行该操作。

JLS参考是JLS 5.6.2: Binary Numeric Promotion


已经指出,在硬件级别可能还会发生其他转换。例如,JLS这样说:

  

在一个不受FP限制的表达式中,为实现提供了一定的回旋余地,以使用扩展的指数范围来表示中间结果;粗略地说,最终结果是,在独占使用浮点值集或双精度值集可能导致上溢或下溢的情况下,计算可能会产生“正确答案”。

但是:

  • 仅当表达式不是strictfp时才允许。
  • 这些不是JLS在5.6.2中提到的“转换”。
  • 这仍然与OP的老师的说法相矛盾。他(或她)说 all 浮点计算是使用double完成的。 JLS指出,在某些情况下,硬件平台 可以使用扩展精度算法(精度可能比64位浮点更高),而在其他情况下,它会不能这样做

答案 2 :(得分:0)

嗨,浮点值JVM使用以下指令:

'+':fadd:弹出两个浮点,将它们相加,然后推浮点结果
 '-':fsub:弹出两个浮点数,减去它们并推入浮点数

类似地,还为*和/等其他运算符设置了其他指令。

因此,按照JVM实现的观点,float + float将导致float。
但是float + double将导致结果翻倍。

有关更多信息,请阅读第14章。浮点算法  《 Inside Java Virtual Machine》一书中的内容

答案 3 :(得分:0)

其他答案缺少的是硬件级别。通常,浮点处理器将所有运算转换为双精度(或四进制),然后以请求的精度返回结果。 Java规范可能无法识别转换,但是如果使用浮点硬件,则会发生转换。