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