今天,我定义了两个浮点变量 f1 和 f2 。然后我执行加法运算“ +”,并将其分配给浮点变量 f 。
float f1 = 0.5048076923076923F;
float f2 = 0.5048076923076923F;
float f = f1 + f2;
根据此图片,算术运算中的所有浮点值( float 和 double ) +,-,*,/ )将转换为 double 类型:
图片来源:http://www.mathcs.emory.edu/~cheung/Courses/170/Syllabus/04/mixed.html
我发现了一个相同的问题,但没有解释原因。为什么月食没有任何提示?是 “ f1 + f2” 的值是浮点型的原因吗?并且,为什么Java会如上图所示自动将double转换为float类型?
PS:英语不是我的母语,如果这个问题有语法问题,请原谅我。谢谢。 :)
答案 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.5048076923076923F
是float
。尾随F
使其成为float
。如果您要使用双精度字面量,请不要使用F
或将其替换为D
。
当您的老师说“所有浮点值都转换为double
”时,他是错误的。 JLS表示(实际上)当另一个操作数是double
时,数字基元操作数将转换为double
。如果两个操作数均为float
,则将使用单精度浮点算法执行该操作。
JLS参考是JLS 5.6.2: Binary Numeric Promotion。
已经指出,在硬件级别可能还会发生其他转换。例如,JLS这样说:
在一个不受FP限制的表达式中,为实现提供了一定的回旋余地,以使用扩展的指数范围来表示中间结果;粗略地说,最终结果是,在独占使用浮点值集或双精度值集可能导致上溢或下溢的情况下,计算可能会产生“正确答案”。
但是:
strictfp
时才允许。 double
完成的。 JLS指出,在某些情况下,硬件平台 可以使用扩展精度算法(精度可能比64位浮点更高),而在其他情况下,它会不能这样做。答案 2 :(得分:0)
嗨,浮点值JVM使用以下指令:
'+':fadd:弹出两个浮点,将它们相加,然后推浮点结果
'-':fsub:弹出两个浮点数,减去它们并推入浮点数
类似地,还为*和/等其他运算符设置了其他指令。
因此,按照JVM实现的观点,float + float将导致float。
但是float + double将导致结果翻倍。
有关更多信息,请阅读第14章。浮点算法 《 Inside Java Virtual Machine》一书中的内容
答案 3 :(得分:0)
其他答案缺少的是硬件级别。通常,浮点处理器将所有运算转换为双精度(或四进制),然后以请求的精度返回结果。 Java规范可能无法识别转换,但是如果使用浮点硬件,则会发生转换。