定義

2010-12-27 6 views
32

sqrt()sin()cos()tan()log()exp()(これらのmath.h/cmath)から入手できるような関数のいずれかの定義がありますか?定義

私はちょうど彼らがどのように動作するのか知りたいと思っていました。

+1

fdlibmはすべてのものの実装を提供し、オープンソースであり、スタンドアロンであり、かなり読みやすいです。彼らはまともなパフォーマンスを提供するように設計されているため、最も単純な実装ではありません。 –

+0

[Cはsin()やその他の数学関数をどのように計算するのですか?](http://stackoverflow.com/questions/2284860/how-does-c-compute-sin-and-other-math-functions) –

答えて

58

これは興味深い質問ですが、効率的なライブラリのソースを読むことは、使用する方法を知っていない限り、あなたをあまり遠ざけません。

古典的な方法を理解するのに役立ついくつかの例を示します。私の情報は決して正確ではありません。以下のメソッドは古典的なメソッドだけですが、特定の実装では他のメソッドを使用できます。

  • ルックアップテーブル頻繁
  • 三角関数がしばしばCORDICアルゴリズム(CPU上またはライブラリーのいずれか)を介して実装されて使用されます。通常正弦と余弦が一緒に計算されることに注意してください、私はいつも標準のCライブラリがsincos関数を提供しない理由を疑問に思っています。
  • 平方根はNewton's methodを使っています。Web上のどこかに、1/sqrt(x)の実装を邪魔しているQuakeのソースコードの抜粋があります。
  • 指数と対数は、引数を0に近づけるためにexp(2^nx)= exp(x)^(2^n)とlog2(2^nx)= n + log2(x) )、有理関数近似を使用します(通常Padé approximants)。この全く同じトリックは行列の指数と対数を得ることができます。 @Stephen Canonによると、近代的な実装では、除算が乗算よりもはるかに遅い有理関数近似よりもテイラー展開が優先されます。
  • 他の機能は、これらの機能から推測できます。実装は、特殊なルーチンを提供してもよい。
  • POW(X、Y)= EXP(Y軸*ログ(X))ので、POW Yが
  • 関数hypot(X、Y)= ABS(X)SQRT(整数であるときに使用されるないありますx> y(そうでなければhypot(y、x))であれば、1 +(y/x)^ 2)となる。 atan2は、sincosと少しロジックを呼び出して計算されます。これらの関数は、複素数演算のビルディングブロックです。
  • 他の超越関数(gamma、erf、bessel、...)については、優れた本Numerical Recipes, 3rd editionを参照してください。 good'old Abramowitz & Stegunも便利です。http://dlmf.nist.gov/に新しいバージョンがあります。
  • Chebyshev近似、継続的な部分拡大(実際にはPadé近似に関連する)、またはべき級数節約などのテクニックは、より複雑な関数で使用されます(たとえば、erf、besselまたはgammaのソースコードを読み取る場合)。ベアメタルの簡単な数学関数で実際に使用されているとは思えますが、誰が知っていますか?概要については数値レシピを参照してください。
+9

+1実際に数学を説明してください。私はtrig関数が単なるTaylor級数の拡張であることを実感したときにはずっと良くなっていました。さもなければ近似は深刻な魔法のように見える!数値方法の場合は –

+0

+1です。 – birryree

+3

@Ben:一般的に、良いライブラリは切り捨てられたテイラー級数を使用しません。他の多項式近似(Minimax、Chebyshev、Padé)は、より望ましい誤差特性を持ち、少ない演算処理で同じ精度を得ることができます。 –

-15

これらはほとんど常にシステムコールとして実装されています。ソースを見るには、OSソースにアクセスする必要があります。つまり、LinuxやBSDのようなオープンソースのOSを見る必要があります。

+8

「罪」をシステムコールとして?問題のOSが非常にグラフィカルでない限り、それはカーネル空間を無駄にしてしまいます。コンテキスト切り替えのためにRTLの実装よりも遅くなります。 sin、cosなどを計算することができる*命令*がありますが、システムコールはありますか?疑わしい。 – cHao

+6

ほとんどありません。関数は、通常のC呼び出しであり、コンパイラまたはCライブラリによって提供されます。 FPUのないシステムの場合、これらの関数が使用する命令はOSによってトラップされ、エミュレートされる可能性がありますが、これはまれなケースです。 – wnoise

+3

数学関数はシステムコールとして実装されていますか?本当に?? –

21

すべての実装は異なる場合がありますが、glibc(GNU Cライブラリ)のソースコードから1つの実装をチェックアウトすることができます。

編集:Googleコード検索がオフラインになっているため、古いリンクはどこにもありません。

のglibcの数学ライブラリのソースがここにあります:

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

+0

おかげで興味深いリンクがあります。 :-) – Nawaz

+0

リンクが壊れています... – unkulunkulu

+1

@unkulunkulu - glibcのgit repoへの直接リンクで更新されました。 – birryree

7

glibcマジック、近似とアセンブリの完全な、さまざまな数学関数を実装する方法を見てください。

+0

+1 glibcソースウェアリンクでは、現時点ではサイトが遅いです。 (編集済み) – birryree

+1

Afaikこれらは遅いバージョンであり、より速くアーチに実装されています。特定のサブフォルダ。 – ismail

+0

haha​​私はサイト自体が遅いことを意味した。 – birryree

5

具体的にはfdlibmソースをご覧ください。 fdlibmライブラリは自己完結型であり、各関数には数学の詳細な説明が書かれており、コードは非常に読みやすくなっています。

+0

+1推奨fdlibm –

4

数学のコードをよく見れば、glibcを見るのはお勧めできません。コードはしばしば非常に難しく、glibcの魔法に多く依存しています。 math lib in FreeBSDは、何らかの理由で時には速度が遅くなっても、はるかに読み易くなります(多くはそうではありません)。

複雑な関数の場合、実際の関数では正確なnan/inf/0の扱いはすでに困難ですが、複雑な関数にとっては悪夢です。 C99規格は多くのコーナーケースを定義し、一部のファンクションは10-20コーナーケースを容易にします。あなたは最新のC99 standard documentの別館Gを見てアイデアを得ることができます。そのフォーマットが標準化されていないので、長い倍精度でも難しいです - 私の経験では、長い倍精度のバグがかなりあるはずです。うまくいけば、拡張精度を備えたIEEE754の今後の改訂版は状況を改善するだろう。

+0

コーナーケースについての良い点。いくつかのケースでは簡単にボトルネックになることがあります(MSVCでの 'ldexp'の実装は、関数をかなり役に立たなくします) –

0

ほとんどの最新のハードウェアには、これらの機能を非常に効率的に実装する浮動小数点ユニットが含まれています。