web-dev-qa-db-ja.com

cmathでのsqrt、sin、cos、powなどの定義

sqrt()sin()cos()tan()log()exp()(これらはmath.h/cmathから)利用可能ですか?

それらがどのように機能するのか知りたかっただけです。

33

これは興味深い質問ですが、使用されている方法を知らない限り、効率的なライブラリのソースを読んでもそれほど遠くはありません。

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

  • ルックアップテーブルが頻繁に使用されます
  • 三角関数は、多くの場合、 [〜#〜] cordic [〜#〜] アルゴリズム(CPUまたはライブラリのいずれか)を介して実装されます。通常、正弦と余弦は一緒に計算されることに注意してください。標準Cライブラリがsincos関数を提供しないのはなぜかといつも思っていました。
  • 平方根は ニュートン法 をいくつかの巧妙な実装トリックで使用します。Webのどこかに、気が遠くなるような1/sqrt(x)実装を使用したQuakeソースコードからの抜粋があります。
  • 指数および対数は、exp(2 ^ nx)= exp(x)^(2 ^ n)およびlog2(2 ^ nx)= n + log2(x)を使用して、ゼロに近い引数(logの場合は1)を使用し、有理関数近似(通常 パデ近似 )。これとまったく同じトリックで、行列指数と対数を取得できることに注意してください。 @Stephen Canonによると、最新の実装では、除算が乗算よりもはるかに遅い有理関数近似よりもテイラー展開が優先されます。
  • 他の関数はこれらの関数から推測できます。実装は、特殊なルーチンを提供する場合があります。
  • pow(x、y)= exp(y * log(x))なので、powはnotであり、yが整数の場合に使用されます。
  • hypot(x、y)= abs(x)sqrt(1 +(y/x)^ 2)if x> y(hypot(y、x)それ以外の場合)オーバーフローを回避します。 atan2は、sincosの呼び出しと小さなロジックを使用して計算されます。これらの関数は、複雑な算術の構成要素です。
  • 他の超越関数(ガンマ、erf、ベッセルなど)については、優れた本 数値レシピ、第3版 を参照してください。古き良き Abramowitz&Stegun も便利です。 http://dlmf.nist.gov/ に新しいバージョンがあります。
  • Chebyshev近似、連分数展開(実際にはパデ近似に関連)、べき級数経済化などの手法は、より複雑な関数で使用されます(たとえば、erf、ベッセル、またはガンマのソースコードを読み取る場合)。ベアメタルの単純な数学関数で実際に使用されているとは思えませんが、誰が知っていますか。概要については、数値レシピを参照してください。
63
Alexandre C.

実装はそれぞれ異なる場合がありますが、glibc(GNU Cライブラリ)のソースコードから1つの実装を確認できます。

編集:Googleコード検索がオフラインになっているので、私が持っていた古いリンクはどこにも行きません。

Glibcの数学ライブラリのソースは次の場所にあります。

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

21
wkl

glibc が、魔法、近似、アセンブリに満ちたさまざまな数学関数をどのように実装しているかをご覧ください。

7
ismail

間違いなく fdlibm ソースを見てください。 fdlibmライブラリは自己完結型であり、各関数は関連する数学の詳細な説明とともに十分に文書化されており、コードは非常に読みやすいので、それらは素晴らしいです。

5
Daniel Trebbien

数学コードをよく見てきたので、glibcを見るのはお勧めしません。コードを理解するのは非常に難しく、glibcの魔法に大きく依存しています。 FreeBSDのmath lib は、どういうわけか時々遅くなる場合でも、はるかに読みやすくなります(ただしそれほどではありません)。

複雑な関数の場合、主な問題は境界の場合です。実際の関数では、正しいnan/inf/0処理はすでに困難ですが、複雑な関数にとっては悪夢です。 C99標準は多くのコーナーケースを定義しており、一部の関数には簡単に10〜20のコーナーケースがあります。最新の付録G C99標準ドキュメント を見てアイデアを得ることができます。ロングダブルではフォーマットが標準化されていないため、難しいこともあります。私の経験では、ロングダブルではかなりの数のバグが予想されます。うまくいけば、拡張精度を備えたIEEE754の次の改訂版が状況を改善するでしょう。

4

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

0
David Heffernan