cmath 中 sqrt、sin、cos、pow 等的定义

新手上路,请多包涵

Are there any definitions of functions like sqrt() , sin() , cos() , tan() , log() , exp() (这些来自 math.h/cmath)可用吗?

我只是想知道它们是如何工作的。

原文由 Pythagoras of Samos 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

这是一个有趣的问题,但是除非您碰巧知道使用的方法,否则阅读高效库的资源不会让您走得太远。

这里有一些提示可以帮助您理解经典方法。我的信息绝不准确。以下方法仅为经典方法,具体实现可以使用其他方法。

  • 查找表经常使用
  • 三角函数通常通过 CORDIC 算法(在 CPU 上或使用库)实现。请注意,通常正弦和余弦是一起计算的,我一直想知道为什么标准 C 库不提供 sincos 函数。
  • 平方根使用 牛顿方法 和一些巧妙的实现技巧:您可能会在网络上的某个地方找到来自 Quake 源代码的摘录,其中包含令人难以置信的 1 / sqrt(x) 实现。
  • 指数和对数使用 exp(2^nx) = exp(x)^(2^n) 和 log2(2^nx) = n + log2(x) 使参数接近零(对数为一)并使用有理函数逼近(通常是 Padé 逼近)。请注意,这个完全相同的技巧可以得到矩阵指数和对数。根据@Stephen Canon 的说法,现代实现倾向于泰勒展开而不是有理函数逼近,其中除法比乘法慢得多。
  • 可以从这些函数中推导出其他函数。实现可以提供专门的例程。
  • pow(x, y) = exp(y * log(x)),所以当 y 为整数时 使用 pow
  • hypot(x, y) = abs(x) sqrt(1 + (y/x)^2) if x > y (hypot(y, x) 否则)以避免溢出。 atan2 是通过调用 sincos 和一些逻辑来计算的。这些函数是复杂算术的构建块。
  • 对于其他超越函数(gamma、erf、bessel、…),请参阅优秀的书 Numerical Recipes, 3rd edition 了解一些想法。 good’old Abramowitz & Stegun 也很有用。在 http://dlmf.nist.gov/ 上有一个新版本。
  • Chebyshev 逼近、连分数展开(实际上与 Padé 逼近相关)或幂级数经济等技术用于更复杂的函数(例如,如果您碰巧阅读了 erf、bessel 或 gamma 的源代码)。我怀疑它们在裸机简单的数学函数中有真正的用途,但谁知道呢。有关概述,请参阅数字食谱。

原文由 Alexandre C. 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题