C言語で複素数を使う方法とは?

このQ&Aのポイント
  • C言語で複素数を使う方法について詳しく教えてください。
  • 複素数をプログラム上でどのように扱えばいいのかわかりません。
  • C言語で複素数を表現する方法や参考になるプログラムコードがあれば教えてください。
回答を見る
  • ベストアンサー

C言語の複素数についてです。

C言語で複素数を使うことになりましたが、複素数をプログラム上でどう使うかわかりません。 粒子の複素屈折率を計算してシミュレーションするというものです。 その複素屈折率は 0.57+2.74i と表されます。iが虚数です。 一般的にCプログラムで複素数を使えるようにする一番簡単な方法はなんでしょうか? 具体的に参考にできるプログラムコードとかあれば是非教えて下さい。 #define complex とか使うのでしょうか? おそらくcomplexというものを使うんだとは思います。実数部と虚数部を分けて考えるのでしょうか。 C言語、いまいちよくわからなくて……どなたか詳しい方、教えて下さい。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.4

C自体,以下の3種類の複素数型をサポートしています。 float _Complex double _Complex long double _Complex ref) ISO/IEC 9899:1999 6. Lanugages / 6.2 Concepts / 6.2.5 Types / Paragraph 11 加減乗除は通常の演算子を利用して可能です。 虚数単位は<complex.h>で定義されるため,実質的には<complex.h>のインクルードが必要になります。 ref) 同 7.Library / 7.3 Complex arithmatic <complex.h> / Paragraph 4 ただし,複素数型はC99と呼ばれる,1999年改正の規格でサポートされた型です。 コンパイラによってはC99を(一切 or 部分的に)サポートしていない場合があります。 複素数型をサポートしていない倍,double _Complexなどの複素数型や,通常の演算子を使っての演算はできません。 その場合は,処理系が複素数演算のためのライブラリを独自に用意してくれているかもしれません。

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

そして #include <complex.h> のもとでは #define complex _Complex が有効になるので double complex なども使える, ですよね>#4. なお Visual Studio 2010 の VC には complex.h が存在しない模様. それにしても #3 に出てくる「クラスをサポートするC」ってなんだろ....

noname#221368
noname#221368
回答No.3

 #define ディレクティブで複素数計算を実現する事は可能ですが、現在では少々古い方法になり、今ではクラスを用いてcomplex型を、自前で定義するのが標準だと思います。ただしクラスをサポートするCなら、自前で定義しなくても、事前にcomplex型がサポートされているとは思います。  complexクラス定義の内容は、概ね以下のようになるはずです。   1)クラスに、complex(複素数型)という名前をつける.      2)代入操作を定義する関数を書く(一般にコンストラクターと呼ばれます).    complex n = 0.57 + 2.4 * I; などを可能にするため.   3)複素数用の四則演算を可能にする関数を書く.   4)実部,虚部,絶対値を取りだす関数を書く.   5)複素共役に関する関数を書く.  1)~5)ではもちろん、実数部と虚数部を分け、実数に関する演算を用いて、必要な関数を定義します。このような内容は通常、拡張子hのヘッダーファイルと呼ばれるファイルにまとめますが、それが#1さんの仰る「#include <complex.h>」の「complex.h」になりますので、まずコンパイラーがcomplex型をサポートするかどうか、調べるのが先決です。 >C言語、いまいちよくわからなくて……  どんな言語でも、純粋な言語リファレンスの部分は、同一です。   1)四足演算.   2)二値判断分岐.   3)繰り返しループ.   4)配列.  どんなプログラムも、上記4つの組み合わせで書かれますし、多くは数学の数式と同じです。例えば、1)は+,-,*,/ の事だし、4)は行列と思えばそれまでです。  むしろ良くわからないのは、コンパイラーへの指示の部分です。 >#include <stdio.h> >#include <complex.h>  #includeディレクティブは、<stdio.h>や<complex.h>の内容を続くコードに合体させてコンパイルせよという、コンパイラーへの指示になっています。これのあるおかげで、 >printf("%f\n", creal(n)); が動作します。<stdio.h>の内容は、モニターへの入出力関数で、この中でprintf関数が定義されています。creal関数は、複素数nの実部取り出しで、<complex.h>で定義されます。これらはマニュアルを調べるか、おぼえるしかないですが、きっと講義で教えてくれます。  あと#2さんの仰っている事は、物理の数値計算は倍精度実数型(有効数字16桁)でおやりなさい、という事だと思います。複素数は、実数のペアと同値ですから。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

double complex などの方がよいかもしれません>#1.

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

お使いのコンパイラーが複素数をサポートしていて、 complex.h というヘッダーファイルがあれば、 例えば下のコードのように、 実数部を取り出したり 虚数部を取り出したり 共役複素数の実数部を取り出したり 共役複素数の虚数部を取り出したり などということができます。 他にもいろいろな関数があって、実数の世界でできることは 同じようにできると思います。 調べてみてください。 #include <stdio.h> #include <complex.h> int main(void) { complex n = 0.57 + 2.4 * I; printf("%f\n", creal(n)); printf("%f\n", cimag(n)); printf("%f\n", creal(conj(n))); printf("%f\n", cimag(conj(n))); return 0; }

関連するQ&A

  • C言語で複素数の計算を行いたいと思っております。

    C言語で複素数の計算を行いたいと思っております。 プログラミングソフトは、C言語を始めよう!を用いています。 しかし変数定義の仕方が分かりません。 複素計算とは具体的に、 exp( i π) (i は虚数単位)です 最初に#include<complex.h>を行いましたが 変数の定義の方法、exp( i π)の定義の方法が いまひとつわからない状態です。 保存するときに、Cファイルではなく、 拡張子をcppに変更してCPPファイルでコンパイルを行っています。 exp( i π)を計算可能なプログラムを 教えて頂ければ幸いです。 ご面倒かと思いますが 回答お願いします。

  • 複素数について

    虚数単位iを導入すると複素係数多項式の解は複素数の中にある。つまり複素数の代数閉体は複素数というのがありますが、何故なんでしょう。言いたいことは分かるのですが、例えばX^2=iの解も複素数ということになります。どうして多項式の解は複素数の範囲に収まるんでしょうか?哲学的というか直感的な説明を誰かしていただけませんか?

  • C言語で

    C言語で複素行列の和と積を計算するプログラムを作りたいのですが、 よくわからないので教えてほしいです。複素数を構造体で定義して、配列を使えば いいと思うのですが・・・。 ちなみに実数の行列の和と積を求めるプログラムはわかっています。

  • C言語での複素数の四則演算について

    C言語で、大きさ2の配列を2つ使って、複素数の四則演算のプログラムを作るのですが、配列をどう使うか分からず手が出せない状態です。 C言語を始めたばかりですので、基礎的なことしか分かりませんが、回答お願いします。

  • C言語:2つの複素数(分数)の四則演算

    下記のプログラムを組んでみて、発展として分数の形で複素数の四則演算のプログラムを作りたいのですが、どうにもややこしく、困っています。 よろしければ御指導よろしくお願いします。 /* 複素数を表す構造体 2つの複素数の四則演算 */ #include <stdio.h> #include <stdlib.h> typedef struct { double real; /* 実数部分 */ double imag; /* 虚数部分 */ }COMPLEX; /* 二つの複素数の和を返す */ COMPLEX comp_add(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real = x.real + y.real; /* 実数部分の和 */ tmp.imag = x.imag + y.imag; /* 虚数部分の和 */ return (tmp); } /* 二つの複素数の差を返す */ COMPLEX comp_sub(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real = x.real - y.real; /* 実数部分の差 */ tmp.imag = x.imag - y.imag; /* 虚数部分の差 */ return (tmp); } /* 二つの複素数の積を返す */ COMPLEX comp_mul(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real = (x.real * y.real) - (x.imag * y.imag); tmp.imag = (x.real * y.imag) + (y.real * x.imag); return (tmp); } /* 二つの複素数の商を返す */ COMPLEX comp_div(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real =(x.real*y.real+x.imag*y.imag)/(y.real*y.real+y.imag*y.imag); tmp.imag = (x.imag*y.real-x.real*y.imag)/(y.real*y.real+y.imag*y.imag); return (tmp); } int main( int argc, char **argv ) { COMPLEX a, b, c; a.real = strtod( argv[1], NULL ); a.imag = strtod( argv[2], NULL ); b.real = strtod( argv[3], NULL ); b.imag = strtod( argv[4], NULL ); c = comp_add(a, b); /* 複素数の和を c に代入 */ printf( "(%f+j%f)*(%f+j%f)=(%3.1lf+j%3.1lf)\n", a.real,a.imag,b.real,b.imag,c.real,c.imag ); c = comp_sub(a, b); /* 複素数の差を c に代入 */ printf( "(%f+j%f)*(%f+j%f)=(%3.1lf+j%3.1lf)\n", a.real,a.imag,b.real,b.imag,c.real,c.imag ); c = comp_mul(a, b); /* 複素数の積を c に代入 */ printf( "(%f+j%f)+(%f+j%f)=(%3.1lf+j%3.1lf)\n", a.real,a.imag,b.real,b.imag,c.real,c.imag ); c = comp_div(a, b); /* 複素数の商を c に代入 */ printf( "(%f+j%f)+(%f+j%f)=(%3.1lf+j%3.1lf)\n", a.real,a.imag,b.real,b.imag,c.real,c.imag ); return( 0 ); }

  • Excel複素数を小数点2桁でroundupしたい

    Excelで複素数の計算しております。 次のような複素数を小数点2桁でroundupしたいのですが、複素数のroundupは調べても出てきません。 515.47320280042+918.156853094894i 上記の複素数を; 515.47+918.16i のようにしたいのです。 IMREAL、IMAGINARYで実数と虚数部を分けてから、roundupしてそののちまたCOMPLEXで複素数に戻せば出来るのですが、例えばIMROUNUP(xxx,2)みたいな関数はないのでしょうか? 宜しくお願い致します。

  • C言語 構造体 2

    三つの構造体α、β、γの実数部、虚数部の値(実数)をそれぞれ入力し、 (α+γ)(γ+β)を求めて表示せよ。 ただし、複素数を、実数部と虚数部に対応するメンバで構成される構造体として表し、複素数の加算用関数c_add()と乗算用関数c_mul()を作成して、これを利用すること。 これらの関数は、sとtを複素数を表す構造体としたとき、c_add(s,t)、c_mul(s,t)と呼び出すと、それぞれ戻り値として、sとtを加算、または乗算した結果である複素数の構造体を返すものとする。 という問題なのですが。。。。 #include<stdio.h> int main(void){ struct complex{ double real; double imaginary; }; struct complex[3]; double real; double imag; printf("α= "); scanf("%d,&real); scanf(%d,&imag); printf("β= "); scanf("%d,&real); scanf(%d,&imag); printf("γ="); scanf("%d,&real); scanf(%d,&imag); (α+γ)=c_add(α,γ); (β+γ)=c_add(β,γ); (α+γ)(β+γ)=c_mul(α+γ,β+γ) result=(α+γ)(β+γ) printf("result= "); まで友達と考えてみたのですが、このあとどうしたらいいのかわかりません>< どなたかお教えください。。お願いします。。。

  • C言語プログラム

    N次の複素正方行列S,Tの積Uを計算するプログラムを作りたいのですが、実数で正方行列を計算するプログラムと 複素数の積、和のプログラム struct complex { double re; double im; }; を作ったのですが、この二つをまとめるとプログラムができるらしいのですがまとめ方が全然わかりません。どのようにしたらいいかヒントなど教えてください。

  • スネルの法則で複素屈折率を用いてよいのでしょうか?

    例えば、光が媒質1から媒質2へ進むときに、その界面において反射や屈折が生じる場合、スネルの法則が成り立つということは知られています。 n1sinθ1=n2sinθ2  (θ1:入射角、θ2:屈折角) この場合、通常は屈折率として1.0とか1.5などの実数が用いられると思うのですが、今私が考えている媒質(薄膜)は、光の吸収を考慮するために屈折率を複素数表記(複素屈折率N)で表しています。 N=n-ik   (i:虚数、k:消衰係数) この場合、例えばθ2を求めたいときに、θ2は複素数となってしまうのですが、"複素数の角度"というものはアリなのでしょうか?また、それを実数で表記したい場合は、例えば絶対値をとるとか、そういうことをしてもいいのでしょうか? そもそもスネルの法則に複素数を使ってよいのかという問題なのかもしれませんが・・どなたかご存知の方、また参考意見など、なんでもよいのでご教授いただけたら幸いです。

  • C言語でファイルから複素数の値を読み込んで表示させるプログラムを作って

    C言語でファイルから複素数の値を読み込んで表示させるプログラムを作っています。 扱う値が実数のみの場合に関しては問題ないのですが、 複素数を読み込む時には、実数のみの場合や、虚数のみの場合もあり、 どう読み込んでいいか分からず、アドバイスを戴きたいと考えております。 それ以外のデータの取り扱い自体は問題ないと思います。 下は実数の値を読み込むプログラムとデータセット、 それを拡張した複素数の値を読み込むプログラムとデータセットになっております。 アドバイス、よろしくお願いいたします。 -------------------------------------------------------------------------------- /*データセット sample.dat*/ 4 3.5 -2 9 12 37.8 65.4 0.4 79.5 3 23.4 5.3 -------------------------------------------------------------------------------- /*プログラム本体 read.c*/ #include <stdio.h> #include <stdlib.h> #define LOW 3 #define COLUMN 4 int main(void){ int i,j; double x[LOW][COLUMN]; if((fp = fopen("sample.dat","r"))==NULL){ printf("The file is not found. : sample.dat \n"); exit(1); } for(i=0;i<LOW;i++){ for(j=0;j<COLUMN;j++){ fscanf(fp,"%lf",&x[i][j]); } } for(i=0;i<LOW;i++){ for(j=0;j<COLUMN;j++){ printf("%lf\n",x[i][j]); } } return 0; } -------------------------------------------------------------------------------- /*データセット sample_C.dat*/ 4+i i -2 9+i 12 37.8-i 65.4i 0.4+i 79.5 3+i 23.4 5.3 -------------------------------------------------------------------------------- /*プログラム本体 read_C.c*/ #include <stdio.h> #include <stdlib.h> #define LOW 3 #define COLUMN 4 typedef struct{ double re; double im; }C_double; int main(void){ int i,j; C_double x[LOW][COLUMN]; if((fp = fopen("sample_C.dat","r"))==NULL){ printf("The file is not found. : sample_C.dat \n"); exit(1); } /*改良したい読み込み部分*/ for(i=0;i<LOW;i++){ for(j=0;j<COLUMN;j++){ fscanf(fp,"%lf",&x[i][j].re); fscanf(fp,"%lf",&x[i][j].im); } } for(i=0;i<LOW;i++){ for(j=0;j<COLUMN;j++){ if(x[i][j].re!=0){ if(x[i][j].im!=0){ printf("x[%d][%d]=%lf+%lfi\n",i,j,x[i][j].re,x[i][j].im); } else{ printf("x[%d][%d]=%lf\n",i,j,x[i][j].re); } } else{ if(x[i][j].im!=0){ printf("x[%d][%d]=%lfi\n",i,j,x[i][j].im); } else{ printf("x[%d][%d]=0\n",i,j); } } } } return 0; }

専門家に質問してみよう