我有这个公式
B = tan(atan(A) + C)
其中 A 是输入,B 是输出,C 是常数。问题是 sin、cos 和 tan 函数的计算量很大,而且当计算为 4 字节浮点数时,公式的精度损失相当大。我正在优化我的代码,所以即使计算总数高出几倍,有什么方法可以避免使用这些函数?
进一步背景:数字 A、B 和 C 是二维平面上 3 个点的 x/y 坐标的比率
我有这个公式
B = tan(atan(A) + C)
其中 A 是输入,B 是输出,C 是常数。问题是 sin、cos 和 tan 函数的计算量很大,而且当计算为 4 字节浮点数时,公式的精度损失相当大。我正在优化我的代码,所以即使计算总数高出几倍,有什么方法可以避免使用这些函数?
进一步背景:数字 A、B 和 C 是二维平面上 3 个点的 x/y 坐标的比率
根据Wolfram Alpha,tan(atan(A)+C)
可以写为(A+tan(C))/(1-A*tan(C))
.
您可以从切线和公式中轻松地手动得出:
tan(a + b) = (tan a + tan b)/(1 - tan a tan b)。
如果tan
您的数学库中的实现很慢或不准确,则可能存在更快或更精确的实现。
我会假设你的公式是正确的。Mark 的评论基本上归结为 C 必须具有角度单位才能使公式有意义的想法,但如果 C 是比率,那么它将没有适当的单位。马克有一个有效的问题。
最后,您仍然需要计算切线,但您可以做一些事情来提供一些帮助。
首先,对sum 的切线应用一个简单的三角恒等式。这与 tan(atan(A)) = A 相结合,将您的公式简化为
B = (A + tan(C))/(1 - A*tan(C))
因此,您仍然需要计算一个切线,即 C 的切线。(因此预先计算 tan(C) 一次。)没有什么能解决这个问题。
但是,有一些方法可以比 sin(C)/cos(C) 更有效地计算切线。例如,直接级数近似可能更好。或者有一个使用 versine 级数的技巧,它本身比切线级数计算效率更高。对于小角度,它可以快速收敛。您可以使用该 versine 的范围缩小技巧来确保小角度。其他技巧也存在。
atan(A) = atan(x_a/y_a)
对于某些点是矢量(x_a,y_a)
和 Oy 之间的角度。因为C是一个常数,你可以预先计算一些c=(x_c,y_c)
单位长度的向量,并以角度C倾斜Oy。然后cos(atan(A)+C)可以表示为这些向量的内积除以a的长度。从 cos 中,您可以使用主要身份获得棕褐色。最后得到:
B = sqrt((x_a^2 + y_a^2)/(x_a*x_c + y_a*y_c)^2 - 1)
这可能更有效。小心标志。