c++ - cmath 中 sqrt、sin、cos、pow 等的定义

标签 c++ c math cmath definitions

sqrt()sin()cos()tan()log()exp()(这些来自 math.h/cmath)可用?

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

最佳答案

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

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

  • 经常使用查找表
  • 三角函数通常通过 CORDIC 实现算法(在 CPU 上或使用库)。请注意,通常正弦和余弦是一起计算的,我一直想知道为什么标准 C 库不提供 sincos 函数。
  • 平方根使用 Newton's method通过一些巧妙的实现技巧:您可能会在网络上的某个地方找到 Quake 源代码的摘录,其中包含令人难以置信的 1/sqrt(x) 实现。
  • 指数和对数使用 exp(2^n x) = exp(x)^(2^n) 和 log2(2^n x) = n + log2(x) 使参数接近于零(对于 log ) 并使用有理函数逼近(通常为 Padé approximants )。请注意,这个完全相同的技巧可以得到矩阵指数和对数。根据@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 和一些逻辑来计算的。这些函数是复杂算术的构建 block 。
  • 其他超越函数(gamma, erf, bessel, ...)请引用优秀书籍Numerical Recipes, 3rd edition一些想法。好老的Abramowitz & Stegun也很有用。 http://dlmf.nist.gov/ 有新版本.
  • Chebyshev 近似、连分数展开(实际上与 Padé 近似相关)或幂级数节约等技术用于更复杂的函数(例如,如果您碰巧阅读了 erf、bessel 或 gamma 的源代码)。我怀疑它们在裸机简单的数学函数中有真正的用途,但谁知道呢。有关概述,请参阅数字食谱。

关于c++ - cmath 中 sqrt、sin、cos、pow 等的定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4541130/

相关文章:

C++ std::function 返回它自己类型的 vector (再次递归类型)

c++ - Visual Studio中/GL和/LTCG有什么区别

c - "Replay"tcpdump 文件

python - 使用 Box-Muller 方法从正态分布生成值

algorithm - 如何绘制高斯分布曲线

c++ - 如何让 "factory function"返回一个不可复制的对象?

c++ - 系统消息未处理异常

c - 将数组的大小传递给函数

c++ - 为什么 isdigit() 如果为真则返回 2048?

javascript - 当我使用弧度将半圆分成四个部分时,看起来我没有得到一条直线