Java的Math.exp相同的错误保证也适用于StrictMath.exp吗?

问题描述 投票:0回答:1

在Java中,我需要以独立于平台的方式计算

(int)Math.exp(x)
。为了实现平台独立性,我必须使用 StrictMath 来代替:
(int)StrictMath.exp(x)
。不幸的是,我的测量表明
StrictMath.exp
明显慢于
Math.exp

因此,我有了先计算

y = Math.exp(x)
的想法。
Math.exp
的界面表明

计算结果与准确结果的误差必须在 1 ulp 以内。结果必须是半单调的。

所以,如果

(int)(Math.nextDown(y)) == (int)(Math.nextUp(y))
,我可以使用
(int)y
作为结果。只有在极少数情况下
(int)(StrictMath.nextDown(y)) != (int)(StrictMath.nextUp(y))
(结果预计在
int
范围内),我才需要额外评估
(int)StrictMath.exp(x)

如果

StrictMath.exp
具有与
Math.exp
相同的错误保证,则该策略将是正确的。 不幸的是,
StrictMath.exp
界面
中缺少相应的声明。 StrictMath 的 javadoc 只是说

为了帮助确保 Java 程序的可移植性,此包中的一些数值函数的定义要求它们产生与某些已发布算法相同的结果。这些算法可以从著名的网络库 netlib 中以“自由分发数学库”fdlibm 包的形式获得。这些用 C 编程语言编写的算法可以理解为按照 Java 浮点算术规则执行所有浮点运算。

Java 数学库是根据 fdlibm 版本 5.3 定义的。如果 fdlibm 为函数(例如 acos)提供多个定义,请使用“IEEE 754 核心函数”版本(位于名称以字母 e 开头的文件中)。需要 fdlibm 语义的方法有 sin、cos、tan、asin、acos、atan、exp、log、log10、cbrt、atan2、pow、sinh、cosh、tanh、hypot、expm1 和 log1p。

此外,fdlibm 库中的 exp 函数的接口说明了这一点

准确度:根据误差分析,误差始终小于1 ulp(最后一位单位)。

所有这些信息的组合是否真的意味着

StrictMath.exp
Math.exp
具有相同的错误保证?只有 100% 的保证才能让我进行上述优化。

java numeric exp
1个回答
0
投票

所有这些信息的组合是否真的意味着

StrictMath.exp
Math.exp
具有相同的错误保证?

从表面上看1,错误保证是相同的;即小于 1 ulp。但这并不等于说错误是相同的!

使用

StrictMath
的目的并不是保证误差是可能的绝对最小值。相反,重点是保证“可重现”的结果,独立于编程语言、硬件实现等。 而另一面是,

Math

方法(仍然是

2
)没有指定产生与StrictMath等价物逐位相同的结果。正如 Java 17 中的
javadoc
所述:

“与

StrictMath 类的一些数字方法不同,

Math
类的等效函数的所有实现都未定义为返回逐位相同的结果。这种放宽允许性能更好的实现
在严格的情况下不需要重现性
。”


但是,我还没有找到任何说明
Math

StrictMath
等价的内容。

我不认为它们保证是等价的:在任何版本的 Java 中都不保证。事实上,这会与上面的 javadoc 引用
相矛盾。

1 - 这是基于您在问题中引用的文字。
2 - 虽然 Java 17 及更高版本中的所有浮点算术运算都具有

strictfp 语义(请参阅
JEP 306

),但这不会自动扩展到 
Math
    

© www.soinside.com 2019 - 2024. All rights reserved.