インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

インテルの数学ライブラリーの使用

インテルの数学ライブラリーの多くのルーチンは、互換マイクロプロセッサーよりもインテル製マイクロプロセッサーでより高度に最適化されます。

mathimf.h ヘッダーファイルには、インテルの数学ライブラリー関数のプロトタイプが含まれています。

インテルの数学ライブラリーを使用するには、プログラムに、ヘッダーファイル mathimf.h をインクルードしてください。

実関数の使用例

次の例は、インテル® C++ コンパイラーで数学ライブラリーを使用する方法を示します。このプログラムをコンパイルして実行すると、x の正弦が表示されます。

Linux* および macOS*

// real_math.c
#include <stdio.h> 
#include <mathimf.h>

int main() {
 float fp32bits;
 double fp64bits;
 long double fp80bits;
 long double pi_by_four = 3.141592653589793238/4.0;

// pi/4 ラジアン = 約 45 度
 fp32bits = (float) pi_by_four; // pi/4 の float 型の近似値
 fp64bits = (double) pi_by_four; // pi/4 の double 型の近似値
 fp80bits = pi_by_four; // pi/4 の long double 型 (拡張精度) の近似値

// sin(pi/4) = 1/sqrt(2) または約 .7071067
 printf("When x = %8.8f, sinf(x) = %8.8f \n", fp32bits, sinf(fp32bits));
 printf("When x = %16.16f, sin(x) = %16.16f \n", fp64bits, sin(fp64bits));
 printf("When x = %20.20Lf, sinl(x) = %20.20f \n", fp80bits, sinl(fp80bits));

 return 0; 
}

Linux* プラットフォームでは、次のコマンドを使用してサンプルコードをコンパイルします。

iccreal_math.c 

Windows*

// real_math.c 
#include <stdio.h> 
#include <mathimf.h>

int main() {
  float fp32bits;
  double fp64bits;

// /Qlong-double コンパイラー・オプションを指定しなければならない
// 指定しない場合、long double 型が double 型にマップされる 
  long double fp80bits;
  long double pi_by_four = 3.141592653589793238/4.0;

// pi/4 ラジアン = 約 45 度
  fp32bits = (float) pi_by_four;

// pi/4 の float 型の近似値
  fp64bits = (double) pi_by_four; 

// pi/4 の double 型の近似値
  fp80bits = pi_by_four;

// pi/4 の long double 型 (拡張精度) の近似値
// sin(pi/4) = 1/sqrt(2) または約 .7071067
  printf("When x = %8.8f, sinf(x) = %8.8f \n",
  fp32bits, sinf(fp32bits));

  printf("When x = %16.16f, sin(x) = %16.16f \n", 
  fp64bits, sin(fp64bits));

  printf("When x = %20.20f, sinl(x) = %20.20f \n", 
  (double) fp80bits, (double) sinl(fp80bits));

// Microsoft* Windows* で printf() は long double 型の出力をサポートしていない 
// そのため、ここでは fp80bits を double 型にキャストしている 
  return 0; 
}

real_math.c プログラムは、long double データ型を使用しているため、コマンドラインで /Qlong_double コンパイラー・オプションと /Qpc80 コンパイラー・オプションを指定します。

icl/Qlong-double/Qpc80real_math.c

複素関数の使用例

このプログラムをコンパイルして実行すると、次の結果が得られます。

When z = 1.0000000 + 0.7853982 i, cexpf(z) = 1.9221154 + 1.9221156 i

When z = 1.000000000000 + 0.785398163397 i, cexp(z) = 1.922115514080 + 1.922115514080 i

Linux*、macOS*、および Windows*

// complex_math.c
#include <stdio.h> 
#include <complex.h>

int main() {
  float _Complex c32in,c32out;
  double _Complex c64in,c64out;
  double pi_by_four= 3.141592653589793238/4.0;
  c64in = 1.0 + I* pi_by_four;

// 倍精度複素数 1 + (pi/4) * i を作成する
// I は虚数部
  c32in = (float _Complex) c64in;

// 倍精度複素数から単精度複素数を作成する
  c64out = cexp(c64in);
  c32out = cexpf(c32in);

// 次の複素数指数を計算する
// cexp(z) = cexp(x+iy) = e^ (x + i y) = e^x * (cos(y) + i sin(y))
 printf("When z = %7.7f + %7.7f i, cexpf(z) = %7.7f + %7.7f i \n"
 ,crealf(c32in),cimagf(c32in),crealf(c32out),cimagf(c32out));
 printf("When z = %12.12f + %12.12f i, cexp(z) = %12.12f + %12.12f i \n"
 ,creal(c64in),cimag(c64in),creal(c64out),cimagf(c64out));

  return 0; 
}

このサンプルプログラムは、_Complex データ型を使用しているため、コマンドラインで [Q]std=c99 コンパイラー・オプションを指定する必要があります。

Linux* および macOS* では、次のコマンドを使用してサンプルコードをコンパイルします。

icc-std=c99complex_math.c

Windows* では、次のコマンドを使用してサンプルコードをコンパイルします。

icl/Qstd=c99complex_math.c

_Complex データ型は、C プログラムではサポートされていますが、C++ プログラムではサポートされていません。

例外条件

未定義の結果になる引数を使用して数学関数を呼び出した場合、エラー番号がシステム変数 errno に割り当てられます。数学関数エラーは通常、領域エラーまたは範囲エラーです。

領域エラーは、関数で領域外の引数が使用された場合に発生します。例えば、acos の引数は -1 から +1 の間のみと定義されています。このため、acos(-2)acos(3) を評価すると、領域エラーが発生し、戻り値は QNaN になります。

範囲エラーは、数学上は有効な引数を使用して、関数の値が浮動小数点データ型で表現可能な値の範囲を超えた場合に発生します。例えば、exp(1000) を評価すると、範囲エラーが発生し、戻り値は INF になります。

領域または範囲エラーが発生すると、次の値が errno に割り当てられます。

次の例は、EDOM および ERANGE エラーの errno の読み方を示したものです。

// errno.c
#include <errno.h> 
#include <mathimf.h> 
#include <stdio.h> 

int main(void) { 
  double neg_one=-1.0;
  double zero=0.0; 

// 負数の自然対数は領域エラー - EDOM とみなされる
  printf("log(%e) = %e and errno(EDOM) = %d \n",neg_one,log(neg_one),errno); 

// ゼロの自然対数は範囲エラー - ERANGE と見なされる
  printf("log(%e) = %e and errno(ERANGE) = %d \n",zero,log(zero),errno); 
}

errno.c の出力は次のようになります。

log(-1.000000e+00) = nan and errno(EDOM) = 33

log(0.000000e+00) = -inf and errno(ERANGE) = 34

このセクションの数学関数では、適用可能な場合、errno の対応する値が表示されます。

その他の考慮事項

コンパイラーによって、自動的にインライン展開される数学関数もあります。実際にインライン展開される関数は、使用するベクトル化またはプロセッサー固有のコンパイラー・オプションに依存し、異なります。-fno-builtin オプション (Linux* および macOS*) または /Oi- オプション (Windows*) でプログラムをコンパイルすることによって、すべての関数の自動インライン展開を無効にできます。

数学ライブラリー関数の超越関数を呼び出し、デフォルトの最適化オプション以上でコンパイルする場合は、デフォルトの丸めモード (最も近い偶数に丸める) を使用することを推奨します。これらの関数のレイテンシーやスループットが高速な実装では、デフォルトの最も近い偶数に丸めるモードで処理されます。ほかの丸めモードを使用すると、高速な実装で生成される結果は精度が落ちるか、予期しない浮動小数点ステータスフラグが設定されます。これは、数学関数の高速な実装への呼び出しを無効にする -no-fast-transcendentals (Linux* および macOS*) または /Qfast-transcendentals- (Windows*) か、浮動小数点環境でデフォルトの設定を仮定できないことをコンパイラーに知らせる -fp-model strict (Linux* および macOS*) または /fp: strict (Windows*) により回避できます。このオプションは、浮動小数点環境でデフォルトの設定を仮定できないことをコンパイラーに知らせます。

64 ビットの 10 進法超越関数は、2 進法拡張倍精度演算を利用します。

正確な結果を得るには、64 ビットの 10 進法超越関数を呼び出すユーザー・アプリケーションで、x87 ユニットが 80 ビット精度 (64 ビットの 2 進仮数部) で動作することを保証しなければなりません。Windows* のようにデフォルトの x87 精度が 80 ビットでない環境では、/Qpc80 オプションを指定してアプリケーションのソースファイルをコンパイルすることで 80 ビット精度に設定することができます。

デフォルトの精度制御または丸めモードを変更すると、いくつかの数学関数で返される結果に影響する場合があります。

IA-32 およびインテル® 64 アーキテクチャーの Windows* システムで特定のデータ型を使用する場合、次のコンパイラー・オプションは重要です。

  • /Qlong-double:long double データ型 (80 ビット浮動小数点) のサポートが必要なプログラムをコンパイルする場合は、このオプションを使用します。このオプションがなくても、コンパイルは成功しますが、long double データ型は、double データ型にマップされます。

  • /Qstd=c99:_Complex データ型のサポートが必要なプログラムをコンパイルする場合は、このオプションを使用します。

関連情報