在C ++优化器中,您可以指定使用快速浮点运算而不是精确浮点运算。不同之处在于,在快速模式下,它将进行适用于真实世界数学的优化,但在计算机上完成时可能无法产生正确的结果。
可以使用GodBolt使用以下代码和-O2
优化来显示此示例。如果你正在使用clang或gcc,你可以放入-ffast-math
参数来查看这些优化代码的样子。
double mulBy6DivBy12(double x)
{ return 6 * x / 12; }
double divBy2(double x)
{ return x / 2; }
如果没有-ffast-math
参数,它将在mulBy6DivBy12
函数中生成乘法和除法运算,两个函数上的它看起来都是一样的。
我想知道的是在运行时,当由JIT处理时,它是否会执行这些可能不安全的优化?
答案 0 :(得分:3)
Java语言规范中有两个有趣的语句。
第一个是广泛的in JLS section 15.7:
<强> 15.7。评估订单
Java编程语言保证了操作数 运算符似乎在特定的评估顺序中进行评估, 即,从左到右。
这已经是完全保证;即使执行可能是任何顺序,他们也必须以从左到右的评估顺序显示。重新排序浮点运算会打破这种外观,所以不允许这样做。
其次,专门针对浮点运算in JLS section 4.2.4保证:
Java编程语言需要浮点运算 表现得好像每个浮点运算符都舍入其浮点 结果精度。 不精确的结果必须四舍五入到 最接近无限精确结果的可表示值;如果 两个最接近的可表示值同样接近,一个与其相近 选择最低有效位0。这是IEEE 754标准 默认舍入模式称为舍入到最近的。
这清楚地说明了每个(从左到右)操作应如何围绕其结果。这也禁止任何重新排序,如果您按从左到右的顺序执行操作,则会从您获得的结果更改计算结果。