C 数学演算は、 C プログラミング言語の標準ライブラリにある関数のグループで、 基本的な数学関数を実装しています。[1] [2]すべての関数は、何らかの方法で浮動小数点数を使用します。異なる C 標準では、下位互換性はあるものの、異なる関数セットが提供されています。これらの関数のほとんどは、 C++ 標準ライブラリでも使用できますが、ヘッダーが異なります (C ヘッダーも含まれていますが、非推奨の互換性機能としてのみ使用されます)。
機能の概要
数学関数のほとんどは、<math.h>( C++ では ヘッダー) で定義されています。 、、、など<cmath>の整数を操作する関数は、代わりにヘッダー ( C++ では ヘッダー)
で定義されています。abslabsdivldiv<stdlib.h><cstdlib>
角度を操作する関数はすべて、角度の単位としてラジアンを使用します。 [1]
これらの関数のすべてがC89標準で使用できるわけではありません。使用できる関数でも、double浮動小数点引数として型のみを受け入れるため、単精度値を使用するコードではコストのかかる型変換が必要になります。C99 では、および引数floatで動作する新しい関数セットを導入することでこの欠点が修正されました。これらの関数はそれぞれ、およびの接尾辞で識別されます。[3]floatlong doublefl
浮動小数点環境
C99では、浮動小数点環境を細かく制御するための関数と型がいくつか追加されています。[3]これらの関数は、丸めモード、例外が発生する条件、数値がゼロにフラッシュされるタイミングなど、浮動小数点計算に影響するさまざまな設定を制御するために使用できます。浮動小数点環境の関数と型は、<fenv.h>ヘッダー(C++)
<cfenv>で定義されています。
複素数
C99 では、複素数のサポートを提供する新しい_Complexキーワード (およびcomplex便利なマクロ。<complex.h>ヘッダーが組み込まれている場合にのみ使用可能) が追加されています。任意の浮動小数点型は を使用して変更できcomplex、その後、浮動小数点数のペアとして定義されます。C99 と C++ は、複素数をコード互換の方法で実装していないことに注意してください。後者は代わりにクラス を提供します。
std::complex
複素数に対するすべての演算は<complex.h>ヘッダーで定義されます。実数値関数と同様に、fまたはlサフィックスは関数の
float complexまたはバリアントを表します。long double complex
さらに複雑な関数がいくつか「C99 での将来の使用のために予約されています」。[5]実装は、標準ライブラリの一部ではないオープンソース プロジェクトによって提供されています。
型ジェネリック関数
ヘッダーは、および<tgmath.h>で定義されている各数学関数の型汎用マクロを定義します。これにより、数学関数の関数オーバーロードの限定的なサポートが追加されます。同じ関数名を異なるタイプのパラメータで使用できます。実際の関数は、パラメータの型に応じてコンパイル時に選択されます。
<math.h><complex.h>
実数と複素数の両方に対して定義されている関数に対応する各型汎用マクロは、合計 6 つの異なる関数、、およびそれらのバリアントをカプセル化しますfloat。double実数long doubleに対してcomplexのみ定義されている関数に対応する型汎用マクロは、合計 3 つの異なる関数、、および関数のバリアントをカプセル化floatしdoubleますlong double。
C++ 言語には関数オーバーロードのネイティブ サポートが含まれているため、<tgmath.h>互換性機能としてもヘッダーは提供されません。
乱数生成
ヘッダー<stdlib.h>(<cstdlib>C++)は、統計的に乱数を生成するために使用できるいくつかの関数を定義します。[6]
arc4random乱数関数のファミリは POSIX 標準では定義されていませんが、いくつかの一般的な実装で見つかります。libcこれは、漏洩したバージョンのRC4暗号 (したがって「a lleged RC4」) のキーストリーム ジェネレーターを指していましたが、通常はChaCha20などの他の暗号からの異なるアルゴリズムが同じ名前を使用して実装されています。
からのランダム性の品質はrand通常、統計的にランダムであると見なすには弱すぎるため、明示的なシードが必要です。可能な場合はarc4random、 の代わりにを使用することをお勧めしますrand。一部の C ライブラリは、内部的にrandを使用して実装していますarc4random_uniform。
実装
LinuxやBSDなどのPOSIXシステムでは、数学関数 ( で宣言されている) は数学ライブラリ に別途バンドルされています。したがって、これらの関数のいずれかを使用する場合は、リンカーにディレクティブ を指定する必要があります。実装にはさまざまなものがあり、次のようになります。
<math.h>libm-lmlibm
- GNU libcの libm
- AMDのlibm、github、Windowsでほぼそのまま使用される
- インテル C++ コンパイラlibm
- Red Hatの libm (Newlib)
- Sunの FDLIBM はFreeBSDの msun とOpenBSDの libm の基盤として使用され、これらは両方ともJuliaの OpenLibmの基盤となりました。
- muslのlibmはBSD
libmsとArmのような他のプロジェクトに基づいています - LLVMのlibmは正しく丸められています(つまり、数学的に正しい結果からの誤差は最終的に0.5単位未満です)[7]
- Arénaire プロジェクトの CRlibm (正しく丸められた libm) とその後継の MetaLibm は、Remez アルゴリズムを使用して、正式に証明された近似値を自動的に生成します。
- RutgerのRLIBMは単精度で正しく丸められた関数を提供します。[8]
必ずしも という名前ではない実装にはlibm次のものがあります:
- Armの最適化された数学ルーチン
- GCE-Mathは、C++用に書かれたC/C++数学関数のバージョンです
constexpr(コンパイル時計算) - CORE-MATH、単精度と倍精度で正しく丸められます。
- SIMD(ベクトル化)数学ライブラリには、SLEEF、Yeppp!、Agner FogのVCLのほか、SVMLやDirectXMathなどのクローズドソースのライブラリもいくつかあります。[9]
参照
参考文献
- ^ ab ISO/IEC 9899:1999 仕様(PDF)。p. 212、§ 7.12。
- ^ Prata, Stephen (2004). C primer plus . Sams Publishing. 付録 B、セクション V: C99 追加機能を備えた標準 ANSI C ライブラリ。ISBN 0-672-32696-5。
- ^ ab Prata, Stephen (2004). C primer plus . Sams Publishing. 付録 B、セクション VIII: C99 数値計算の強化. ISBN 0-672-32696-5。
- ^ 表記上、平方または立方を計算するにはpow( x ,2) または pow( x ,3) を使用すると便利に思えるかもしれません。ただし、これは時間重視のコードではお勧めできません。実装でコンパイル時にこれらのケースに特別な配慮をしない限り、 x * xまたはx * x * xの方がはるかに高速に実行されます。また、 sqrt( x ) と cbrt( x ) は、 pow( x ,.5) または pow( x ,1./3)よりも優先されます。
- ^ man cerf(3)、man cerfc(3)、例えば https://linux.die.net/man/3/cerf を参照してください。
- ^ 「GNU C ライブラリ – ISO ランダム」 。2018年7 月 18 日閲覧。
- ^ 「数学関数 — LLVM C ライブラリ」. libc.llvm.org .
- ^ 「RLibm: ラトガース大学のアーキテクチャとプログラミング言語ラボの正しく丸められた Libm」。people.cs.rutgers.edu。
- ^ Cordes, Peter. 「intel - Clang の '_mm256_pow_ps' 組み込み関数はどこにありますか?」. Stack Overflow .
外部リンク
- : 数学的宣言 – 基本定義リファレンス、The Single UNIX 仕様、バージョン 4、The Open Group
- 数学関数のCリファレンス
