【问题标题】:Why will Java convert the double to float type in this situation?为什么Java会在这种情况下将double类型转换为float类型?
【发布时间】:2019-03-03 02:32:10
【问题描述】:

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

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

这是输出:

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

我发现了一个相同的问题,但没有解释原因。为什么eclipse没有任何问题提示?难道是"f1 + f2"的值是float类型的原因吗?而且,如果像上图所说的那样,为什么Java会自动将double类型转换为float类型?

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

【问题讨论】:

  • 两个float(s) 相加的结果是float。据我所知,float(s) 在算术之前没有扩大到double。这种说法没有任何意义。
  • 可能是他只是复制粘贴了一个双精度文本而忘记修改它。
  • 可能我表达的不是很清楚,但是Stephen C的回答已经解决了这个问题。我之前的想法是两个浮点数将转换为双精度类型。感谢您的帮助。 :D

标签: java eclipse


【解决方案1】:

您似乎在说下面有到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 在 JLS 5.6.2 中谈到的“转换”。
  • 这仍然与 OP 老师所说的相矛盾。他(或她)声明 all 浮点计算是使用double 完成的。 JLS 声明在某些情况下,硬件平台可能使用扩展精度算术(可能比 64 位浮点精度更高),而在其他情况下千万不要这样做

【讨论】:

  • 非常感谢您的回答。这个答案很好地解决了我的问题。我要告诉我的老师。 ?
【解决方案2】:

你的老师说的不对,请指教section 5.6.2 of the Java Language Specification,上面写着:

  • 加宽原语转换(第 5.1.2 节)适用于转换以下规则中指定的一个或两个操作数:

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

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

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

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

如您所见,浮点数仅在另一个操作数是双精度数时才转换为双精度数,并非在所有情况下都如您的教学大纲错误地指出的那样。

也就是说,两个浮点数的和是一个浮点数,但是一个浮点数和一个双精度数的和是一个双精度数。

PS:不,Java 永远不会将双精度浮点数转换为浮点数,除非您明确要求,如:

float f = (float) Math.PI;

【讨论】:

    【解决方案3】:

    对于浮点值,JVM 使用如下指令:

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

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

    因此,根据 JVM 实现的观点,float + float 将导致浮动。
    但是 float + double 会导致加倍。

    有关更多信息,您可以阅读第 14 章。浮点运算 《Inside Java Virtual Machine》一书的内容

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • .... 除非您使用 strictfp。此外,这些转换并不是 JLS 使用术语“转换”时的意思。事实仍然是,OP 的老师说(没有资格)计算总是使用双重算术执行......根据你所说的......由于 两个 原因是错误的.
      猜你喜欢
      • 1970-01-01
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 2013-08-15
      相关资源
      最近更新 更多