Math.atan2的文档说
它说2 ulps的事实可能意味着在某些情况下返回的值不是最接近真实结果的double
。有谁知道是否保证对相等的int
参数对返回相同的值?换句话说,如果a
,b
和k
是正int
值,并且a * k
和b * k
都不会溢出,则可以确保
Math.atan2(a, b) == Math.atan2(a * k, b * k)
编辑
注意,对于非溢出的
long
乘法,绝对不是这种情况。例如long a = 959786689;
long b = 363236985;
long k = 9675271;
System.out.println(Math.atan2(a, b));
System.out.println(Math.atan2(a * k, b * k));
版画
1.2089992287797169
1.208999228779717
但我找不到
int
值的示例。 最佳答案
简单地说,不。 Math
文档是事实的来源,它不能保证您引用的2 ulp限制之外。这是设计使然(我们将在下面看到),因此任何其他来源都在暴露实现细节或完全错误。
尝试试探性地找到下界是不切实际的,因为 Math
的行为被证明是特定于平台的:
因此,即使您在测试中看到了更严格的界限,也没有理由相信这些界限可以跨平台,处理器或Java版本移植。
但是,正如Math
的文档说明所述, StrictMath
具有更明确的行为。已记录StrictMath
在各个平台上均能一致地执行,并且应具有与引用实现 fdlibm
相同的行为。该项目的 readme
注意:
您可以引用source code for atan2
并通过检查其实现来确定精确范围。 StrictMath.atan2()
的任何其他实现都需要提供与引用实现相同的结果。
有趣的是,StrictMath.atan2()
不包含与Math.atan2()
相同的2 ulp注释。如果可以明确地重复fdlibm
的“在一个ulp以下”注释会很好,但我认为缺少此注释意味着StrictMath
的实现不需要包括该警告-它始终会低于一个ulp。
tl;博士如果需要精确结果或跨平台稳定结果,请使用StrictMath
。 Math
在精度与速度之间进行权衡。
关于java - 关于Math.atan2的保证,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37355486/