sqrt()
、sin()
、cos()
、tan()
、log()
、exp()
(これらはmath.h/cmathから)利用可能ですか?
それらがどのように機能するのか知りたかっただけです。
これは興味深い質問ですが、使用されている方法を知らない限り、効率的なライブラリのソースを読んでもそれほど遠くはありません。
ここに、古典的な方法を理解するのに役立ついくつかの指針があります。私の情報は決して正確ではありません。以下のメソッドは古典的なメソッドのみであり、特定の実装では他のメソッドを使用できます。
sincos
関数を提供しないのはなぜかといつも思っていました。atan2
は、sincos
の呼び出しと小さなロジックを使用して計算されます。これらの関数は、複雑な算術の構成要素です。実装はそれぞれ異なる場合がありますが、glibc(GNU Cライブラリ)のソースコードから1つの実装を確認できます。
編集:Googleコード検索がオフラインになっているので、私が持っていた古いリンクはどこにも行きません。
Glibcの数学ライブラリのソースは次の場所にあります。
glibc
が、魔法、近似、アセンブリに満ちたさまざまな数学関数をどのように実装しているかをご覧ください。
間違いなく fdlibm ソースを見てください。 fdlibmライブラリは自己完結型であり、各関数は関連する数学の詳細な説明とともに十分に文書化されており、コードは非常に読みやすいので、それらは素晴らしいです。
数学コードをよく見てきたので、glibcを見るのはお勧めしません。コードを理解するのは非常に難しく、glibcの魔法に大きく依存しています。 FreeBSDのmath lib は、どういうわけか時々遅くなる場合でも、はるかに読みやすくなります(ただしそれほどではありません)。
複雑な関数の場合、主な問題は境界の場合です。実際の関数では、正しいnan/inf/0処理はすでに困難ですが、複雑な関数にとっては悪夢です。 C99標準は多くのコーナーケースを定義しており、一部の関数には簡単に10〜20のコーナーケースがあります。最新の付録G C99標準ドキュメント を見てアイデアを得ることができます。ロングダブルではフォーマットが標準化されていないため、難しいこともあります。私の経験では、ロングダブルではかなりの数のバグが予想されます。うまくいけば、拡張精度を備えたIEEE754の次の改訂版が状況を改善するでしょう。
最新のハードウェアのほとんどには、これらの機能を非常に効率的に実装する浮動小数点ユニットが含まれています。