在cmath中sqrt,sin,cos,pow等的定义

Pat*_*ski 33 c c++ math cmath definitions

有没有像功能的任何定义sqrt(),sin(),cos(),tan(),log(),exp()(这些从文件math.h/CMATH)可用?

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

Ale*_* C. 63

这是一个有趣的问题,但阅读有效库的来源不会让你走得太远,除非你碰巧知道所使用的方法.

这里有一些指导可以帮助您理解经典方法.我的信息绝不准确.以下方法仅是经典方法,特定实现可以使用其他方法.

  • 经常使用查找表
  • 三角函数通常通过CORDIC算法实现(在CPU上或库中).请注意,通常一起计算正弦和余弦,我总是想知道为什么标准C库不提供sincos函数.
  • 平方根使用牛顿的方法和一些聪明的实现技巧:你可以在网上的某个地方找到Quake源代码的摘录,其中包含1/sqrt(x)实现的思维.
  • 指数和对数使用exp(2 ^ nx)= exp(x)^(2 ^ n)和log2(2 ^ nx)= n + log2(x)使参数接近于零(对于log为1)并使用有理函数逼近(通常是Padé逼近).请注意,这个完全相同的技巧可以获得矩阵指数和对数.根据@Stephen Canon的观点,现代实现有利于泰勒扩展而不是有理函数逼近,其中除法比乘法慢得多.
  • 其他功能可以从这些功能中推断出来.实现可以提供专门的例程.
  • pow(x,y)= exp(y*log(x)),因此当y是整数时使用pow
  • hypot(x,y)= abs(x)sqrt(1 +(y/x)^ 2)如果x> y(否则为hypot(y,x))以避免溢出.atan2通过调用sincos和一点逻辑来计算.这些函数是复杂算术的构建块.
  • 对于其他超越函数(gamma,erf,bessel,...),请参阅优秀的书籍Numerical Recipes,第3版了解一些想法.好老的Abramowitz&Stegun也很有用.http://dlmf.nist.gov/上有一个新版本.
  • 像Chebyshev近似,连续分数扩展(实际上与Padé近似相关)或幂级数节约等技术用于更复杂的函数(例如,如果您碰巧读取erf,bessel或gamma的源代​​码).我怀疑它们在裸机简单的数学函数中有用,但是谁知道呢.有关概述,请参阅Numerical Recipes.

  • +1实际解释数学.当我意识到触发功能只是被截断的泰勒系列扩展时,我感觉好多了.否则近似看起来像严重的魔法! (10认同)
  • @Ben:好的库通常不使用截断的泰勒系列 - 其他多项式近似(Minimax,Chebyshev,Padé)具有更理想的误差特性,并且允许用更少的算术运算获得相同的精度. (3认同)
  • @Alexandre:理性近似对于`exp`和`log`来说已经过时了,因为乘法和加法比现代硬件上的除法快得多.但是,它仍然用于更硬的功能. (2认同)

wkl*_*wkl 21

每个实现可能都不同,但您可以从glibc(GNU C库)源代码中查看一个实现.

编辑:Google代码搜索已脱机,因此旧链接无处可去.

glibc数学库的来源位于:

http://sourceware.org/git/?p=glibc.git;a=tree;f=math;h=3d5233a292f12cd9e9b9c67c3a114c64564d72ab;hb=HEAD


ism*_*ail 7

看看如何glibc实现各种数学函数,充满魔力,近似和装配.

  • 大声笑,互联网总是很慢,这里看不出差异;) (2认同)

Dan*_*ien 5

绝对看看fdlibm来源.它们很好,因为fdlibm库是独立的,每个函数都有详细记录,详细解释了所涉及的数学,并且代码非常清晰易读.