• ベストアンサー

Cでの複素数の表し方

lapackで行列の固有値を求めようとしています。言語はCです。 行列要素を入力したいのですが、例えば A[2]=c2*sqrt(3)fi (c2はdouble型の定数)と入力してもfiの部分を読み取ってくれません。 ただ、これを数字で入力(例えば、A[2]=2.34fi)すると、きちんと虚部を認識してくれます。 どこが間違っているのか、どなたか教えて下さい。 また、説明不足がありましたらご指摘下さい。  

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

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.1

>A[2]=2.34fi)すると、きちんと虚部を認識してくれます。 「fiは複素数」と言うのが間違っています。 2.34 ⇒ double型の2.34 2.34f ⇒ float型の2.34 2.34F ⇒ float型の2.34 2.34L ⇒ real型の2.34 2.34i ⇒ double型の2.34の複素数 2.34fi ⇒ float型の2.34の複素数 2.34Fi ⇒ float型の2.34の複素数 2.34Li ⇒ real型の2.34の複素数 つまり「fi」は「接尾辞fの後ろに、接尾辞iが付いた物」であり「前置されたリテラル値がfloat型で、しかも複素数である」と言う意味なのです。 「リテラル値の接尾辞」である限りは「リテラルのうしろにしか付かない」のです。 結果を格納する「A[2]」がdouble型なのであれば A[2]=2.34fi と書いてはいけません。こう書くと右辺値がfloat型なので、float⇒doubleへの「暗黙の型キャスト」が行われてしまいます。double値をdouble型に格納すれば型キャストは起きないので A[2]=2.34i と書きましょう。 当然 A[2]=c2*sqrt(3)fi は間違いなので A[2]=c2*sqrt(3)*1.0i と書かなければなりません。 c2が「定数」だとしても、c2は「リテラルではなく、識別子」なので「c2i」や「c2 i」とは書けません。 「複素数はリテラルな定数の後ろにiを足して表す」と覚えましょう。

その他の回答 (1)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

2.34fiというのはGCCの方言ですね。 一般的には2.34f*Iとします。また、この場合、<complex.h>をインクルードする必要があります。 A[2]=c2*sqrt(3)fi については、A[2]=c2*sqrt(3.0f)*Iとする必要があります。 このとき、<complex.h>に加えて<tgmath.h>もインクルードしてください。 Cygwinなどのように、<tgmath.h>をサポートしない処理系の場合、<tgmath.h>のインクルードはやめてください。ただし、若干意味が変わりますので、その点については要注意です。

関連するQ&A

  • 複素数の固有値の求めるプログラムについて

    現在、C言語でプログラムを組んでいるのですが、複素数からなる行列の固有値を求めるプログラムがどうしてもつくることができません。 インターネットやプログラムのパッケージなどを調べてみたのですが、実数からなる行列の固有値を求めるプログラムしか載っておらず、勉強不足によりそれを複素数の場合に拡張することもできませんでした。 もしよければ、プログラムの組み方や実数のプログラムから複素数のプログラムへの替え方のこつ、もしくは「この本に載っていたよ」など、どんな情報でもかまいませんので教えて頂けないでしょうか? すいませんがよろしくお願いします。

  • 複素数

    2次方程式 ax^2 + bx + c = 0 の解を解の公式を使って求めようと思っています。 ただし分数などは使わずに、小数で表記する(小数第3位まで)とします。 ※例えば x^2 + 4x + 2 = 0 の場合 x = -0.586 , -3.414 となります。 では、複素数の場合はどうなるのでしょうか。 x^2 + x + 1 = 0 の場合、解は(-1±√(3)i)/2 となりますが、これを小数で表記することは可能なのでしょうか。 ※x = -0.586 , -3.414 はExcelで以下のようにして求めました。 A1,B1,C1にa,b,cの係数を入力し、 A2に=(-B1+SQRT(B1^2-4*A1*C1))/(2*A1)、 B2に=(-B1-SQRT(B1^2-4*A1*C1))/(2*A1) と入力しました。

  • C++でのプログラムについての質問です

    このような二次関数の解を求めるプログラムを作成したのですが、自作関数solveをvoid solve(double, double, double)のように変更し同じ動作をするように変更したいです どのようにへんこうすればよいでしょうか #include<stdio.h> #include<stdlib.h> #include<math.h> int main(void) { double a, b, c; /*二次方程式の定数*/ double D, x1, x2, r1, r2; printf("ax^2 + bx + c = 0 の係数 a, b, c を入力してください---> \n"); scanf_s("%lf %lf %lf", &a, &b, &c); printf("2次方程式を解いた結果は次の通りとなる。\n"); if (a == 0.0) { if (b == 0.0) { printf("係数がおかしい\n"); exit(-1); } { x1 = -c / b; printf("解は%f です。\n", x1); exit(0); } } else { D = b * b - 4 * a * c; if (D >= 0) { x1 = (-b + sqrt(D)) / (2.0 * a); x2 = (-b - sqrt(D)) / (2.0 * a); if (D == 0.0) { printf("解は %f です。\n", x1); } else { printf("解は %f と %f です。¥n", x1, x2); } } else { r1 = -b / (2 * a); r2 = sqrt(-D) / (2 * a); printf("解は%.2f+%.2fi と%.2f-%.2fi \n", r1, r2, r1, r2); } } return 0; }

  • MATLABとC++

    こんにちわ。資料を参考にしつつMATLABからC言語へ変換する作業をしているのですが、どちらに関しても初心者レベルで遅々としてはかどりません…。 分からないことの一つとして、MATLABは行列計算がしやすいがC言語はそうではないということからなのですが、MATLABで A = zeros(10,20,30) というのは次元10×20×30をもつゼロ行列 ということは分かったのですが、これは 数学で習う行列、2×2 や3×3など二次元な数字の並びを、三次元にまで拡張した表し方ということでしょうか?? また、上の式をC言語で書き表すとすると どのように書き表せるのでしょうか?どなたか分かるかた 教えていただければと思います。

  • C言語 行列 配列

    現在、C言語を勉強中です。 C言語で (10000*10000)の大きさの行列を扱いたいです。 double a[10000][10000]の配列ではメモリ不足となってしまいます。 このような場合はどのようにプログラムを組んでいったら良いのでしょうか?

  • C++でのプログラミングについてです

    プログラミング初心者です C++で二次方程式の解のプログラムを作成したのですがうまく作動させることができません…どこがおかしいのでしょうか、またどのように変更すればよいでしょうか 発生したエラーは 15行 型voidの値をintのエンティティに割り当てることはできません 34行 宣言が必要です 55行 宣言が必要です 15行 voidが他の型と同時に使われました 34行 '{'を見つけました(関数のヘッダーがないかもしれません). 68行 構文エラー:'}' です よろしくお願いいたします #include<stdlib.h> #include<math.h> void solve(double, double, double); int main(void) { double a, b, c; /*二次方程式の定数*/ double D, x1, x2, r1, r2; int ret; printf("ax^2 + bx + c = 0 の係数 a, b, c を入力してください---> \n"); scanf_s("%lf %lf %lf", &a, &b, &c); printf("2次方程式を解いた結果は次の通りです。\n"); ret = solve(a, b, c, &x1, &x2, &r1, &r2); switch (ret) { case-1: printf("係数がおかしい\n"); break; case 0: printf("解は虚数解で%.2f+%.2fi と%.2f-%.2fi です\n", r1, r2, r1, r2); break; case 1: printf("解は実数解となり、%f です。\n", x1); break; case 2: printf("解は実解解で、%f と %f です。¥n", x1, x2); break; } return 0; } void solve(double a, double b, double c, double x1, double x2, double r1, double r2); { if (a == 0.0) { if (b == 0.0) { return -1; } { x1 = -c / b; return 1; } } else { D = b * b - 4 * a * c; if (D >= 0) { x1 = (-b + sqrt(D)) / (2.0 * a); x2 = (-b - sqrt(D)) / (2.0 * a); return 1; } if (D == 0) { x1 = -b / (2 * a); return 1; } else { r1 = -b / (2 * a); r2 = sqrt(-D) / (2 * a); return 0; } } }

  • 2次方程式の解 Cプログラミング

    C言語でのプログラムの添削をお願いします。 2次方程式の解を求めるものなのですが。 #include<stdio.h> #include<math.h> main(){ double a,b,c,d; double x1=0; double x2=0; scanf("%lf %lf %lf" ,&a,&b,&c); printf("a=%f b=%f c=%f\n" ,a,b,c); d=b*b-4*a*c; if(d>0){ x1=(-b+sqrt(d))/2*a; x2=(-b-sqrt(d))/2*a; printf("x=%f,%f\n" ,x1,x2); }else if(d<0){ x1=-b/2*a; x2=sqrt(-d)/2*a; printf("x=%f+%fi,%f-%fi\n" ,x1,x2,x1,x2); }else{ printf("x=%f\n" ,x1); } return 0; } このとき、 a=-7,b=2,c=-1 を与えると x=7.000000+-17.146428i,7.000000--17.146428i という値が返ってきます。 他にも、虚数解のときに間違った値が返ってきてしまう気がするのですが、いかがでしょうか? 実数解のときは正しいようです。 回答よろしくお願いします。

  • ax^2+bx+c=0の解を求めたいのですが・・(初歩的です)

    タイトル通り、a、b、cを入力させて、ax^2+bx+c=0の解xを求めたいのですが、結果をどう求めればいいのか、実解・虚数解・重解の場合をどうしたらいいのか、の2点がよくわかりません。 #include<math.h> #include<stdio.h> double sqrt(double a,double b,double c) { return (b*b-4*a*c); } main(void) { double a,b,c,sqrt,ans; do{ printf("ax^2 + bx +c = 0 の解 x を求めます。\n a,b,cを入力してください。\n"); printf("a : "); scanf("%lf",&a); printf("\nb : "); scanf("%lf",&b); printf("\nc : "); scanf("%lf",&c); if(a = 0){ printf("a は0以外を入力してください。\n"); } }while(a = 0); ans = (-b+dist(a,b,c))/(2*a); printf("%lf", ans); printf("\n"); return(0); } 他にも多々ダメな部分があると思いますがご指摘・アドバイス等いただけたらと思います。よろしくお願いします。

  • 複素関数と行列の関係がわかりません

    「複素数zについて,√zが定められている.このとき,正方行列Aの固有値が,0および虚部が負の純虚数でなければ,√Aが定義できる.これは,Aの固有値を含む領域において正則なzの関数f(z)に対して,f(A)が定義できるためである.」ということを習いました. ここで,質問なのですが,「正方行列Aの固有値が,虚部が負の純虚数でない」という条件はなぜ必要なのでしょうか? √zについてz=rexp(iθ)と極形式で表示して,コーシーリーマンの関係式を調べると,z=0のときは,√zは正則ではないということがわかり,これが「Aの固有値が0でない」ことを要求する理由だと考えました. しかし,r≠0かつθ=-π/2の場合は,√zが正則であるため,Aの固有値として虚部が負の純虚数が存在していても,√Aが定義できると考えてしまいます. ご教授願います.

  • Mapleでsimplifyコマンドが効きません

    宜しくお願い致します。 ユニタリ行列の固有値は実数ですよね。 A:= 100,-1+3*I,1 -1-3*I,50,3-I 1,3+I,10 というユニタリ行列の固有値をMapleで求めたら本来実数値になる筈が下記のようになぜか複素数表示されてしまいました。 どうすればキチンと実数値に表す事ができるのでしょうか? With(LinearAlgebra); にてEigenvalues(A)というコマンドを使ってます。Maple11 simplify(Eigenvalues(A))としても虚数Iがなくなりません。 (1/3)*(90595+(3*I)*sqrt(25097679858))^(1/3)+6163/(3*(90595+(3*I)*sqrt(25097679858))^(1/3))+160/3 -(1/6)*(90595+(3*I)*sqrt(25097679858))^(1/3)-6163/(6*(90595+(3*I)*sqrt(25097679858))^(1/3))+160/3+(1/2*I)*sqrt(3)*((1/3)*(90595+(3*I)*sqrt(25097679858))^(1/3)-6163/(3*(90595+(3*I)*sqrt(25097679858))^(1/3))) -(1/6)*(90595+(3*I)*sqrt(25097679858))^(1/3)-6163/(6*(90595+(3*I)*sqrt(25097679858))^(1/3))+160/3-(1/2*I)*sqrt(3)*((1/3)*(90595+(3*I)*sqrt(25097679858))^(1/3)-6163/(3*(90595+(3*I)*sqrt(25097679858))^(1/3)))

専門家に質問してみよう