プログラミング言語 C の新機能 Part XLV: COMPLEX#3: complex.h: マクロ/プラグマ
(2000/02/21 [月])
_Complex 型や_Imaginary 型を使いやすくするため、および複素数をサポートする関数のために complex.h が作成されました。今回は、このヘッダで定義されるマクロとプラグマについて説明します。
まずプラグマにはついては、以前紹介した
#pragma STDC CX_LIMITED_RANGE
が complex.h を include することで利用可能になります。
そしてマクロについてです。 complex.h では、complex, imaginary, I というマクロが定義されています。これは _Complex 型や _Imaginary 型を使いやすくするためのものです。具体的に定義例を示すと次のようなものです。
まずはじめに言っておく必要があるのは、__STD_IEC_559_COMPLEX__ が定義されている場合のみ、_Imaginary 型が使用できるので、定義されていない場合 _Imaginary 型とそれに関係するものは使用できないということです。
さて complex.h を include すると _Complex や _Imaginary という表記ではなく、complex、imaginary という表記ができるようマクロ定義されます。したがって、double complex val1 のような便利な表記が使用可能になります。
さらに、I (i の大文字)という記号が定義されます。これは何かというと、複素数で用いられる 1.3+4.5i の i をあらわしています。しかし、i という記号は別の用途で広く利用されているので委員会は、I を当てたようです。では実際どのように用いるのか、どうしてこれを用いると複素数型になるのかを見てみましょう。まず、_Imaginary 型が有効な場合について考えます。例として、1.3+4.5i を考えましょう。これは、C 言語の複素数式で書くと 1.3 + 4.5 * I と書けます。
次に _Imaginary 型がサポートされていない場合を考えてみましょう。委員会は、_Imaginary 型がサポートされていない場合でもそれなりにできるよう、複素数型を設計しました。
このように、C 言語では complex.h を include することでかなり自然な表記で複素数を記述することができるようになっています。またこの定義が気に食わない、支障があるような場合、complex、imaginary、I を再定義したり、未定義にしたりすることが許されています。
#2000/03/04: update
まずプラグマにはついては、以前紹介した
#pragma STDC CX_LIMITED_RANGE
が complex.h を include することで利用可能になります。
そしてマクロについてです。 complex.h では、complex, imaginary, I というマクロが定義されています。これは _Complex 型や _Imaginary 型を使いやすくするためのものです。具体的に定義例を示すと次のようなものです。
//complex 型サポート #define complex _Complex #define _Complex_I ((const float _Complex)(_Imaginary)1.0) //↑正確には 0.0+1.0i の値を持つ const float _Complex 型の複素数定数 //この場合は __STD_IEC_559_COMPLEX__ の定義時のみの例 //imaginary 型サポート //以下二つは、__STD_IEC_559_COMPLEX__ が定義されているときのみ #ifdef __STD_IEC_559_COMPLEX__ #define imaginary _Imaginary #define _Imaginary_I ((const float _Imaginary)1.0) #endif //定数 I サポート #ifdef _Imaginary_I #define I _Imaginary_I #else #define I _Complex_I #endif |
まずはじめに言っておく必要があるのは、__STD_IEC_559_COMPLEX__ が定義されている場合のみ、_Imaginary 型が使用できるので、定義されていない場合 _Imaginary 型とそれに関係するものは使用できないということです。
さて complex.h を include すると _Complex や _Imaginary という表記ではなく、complex、imaginary という表記ができるようマクロ定義されます。したがって、double complex val1 のような便利な表記が使用可能になります。
さらに、I (i の大文字)という記号が定義されます。これは何かというと、複素数で用いられる 1.3+4.5i の i をあらわしています。しかし、i という記号は別の用途で広く利用されているので委員会は、I を当てたようです。では実際どのように用いるのか、どうしてこれを用いると複素数型になるのかを見てみましょう。まず、_Imaginary 型が有効な場合について考えます。例として、1.3+4.5i を考えましょう。これは、C 言語の複素数式で書くと 1.3 + 4.5 * I と書けます。
1.3 + 4.5 * I | 通常の計算式同様 * のほうが優先度が高いので 4.5 * I が計算される。I は _Imaginary_I。 |
1.3 + 4.5 * _Imaginary_I | _Imaginary_I を置き換え |
1.3 + 4.5 * ((const float _Imaginary)1.0) | 四則演算のルール、実数型 * _Imaginary 型から結果は _Imaginary 型となる |
1.3 + (const double _Imaginary)4.5 | 四則演算のルール、実数型 + _Imaginary 型から結果は _Complex 型 1.3 + 4.5 iとなる |
(const double _Complex)(1.3 + 4.5*I) | 結果として、1.3 + 4.5 * I は左の定数と同じ意味になる |
次に _Imaginary 型がサポートされていない場合を考えてみましょう。委員会は、_Imaginary 型がサポートされていない場合でもそれなりにできるよう、複素数型を設計しました。
1.3 + 4.5 * I | 通常の計算式同様 * のほうが優先度が高いので 4.5 * I が計算される。I は _Complex_I。 |
1.3 + 4.5 * _Complex_I | _Complex_I は const float _Complex 型の定数 0.0+1.0i と同等の値 |
1.3 + 4.5 * const float _Complex 型の 0.0+1.0i の定数値 | 四則演算のルール、実数型 * _Complex 型から結果は _Complex 型となる |
1.3 + const double _Complex 型の定数値 0.0+4.5i | 四則演算のルール、実数型 + _Complex 型から結果は _Complex 型 1.3 + 4.5 iとなる |
(const double _Complex)(1.3 + 4.5*I) | 結果として、1.3 + 4.5 * I は左の定数と同じ意味になる |
このように、C 言語では complex.h を include することでかなり自然な表記で複素数を記述することができるようになっています。またこの定義が気に食わない、支障があるような場合、complex、imaginary、I を再定義したり、未定義にしたりすることが許されています。
#2000/03/04: update
by seclan