C言語で複素数(分数)の四則演算を行うプログラム

このQ&Aのポイント
  • C言語で複素数の四則演算を行うプログラムの組み方について困っています。発展として分数の形で計算する方法も学びたいです。
  • プログラムの中で複素数の和、差、積、商を計算する関数を定義しました。しかし、実装がややこしく理解できません。
  • 複素数の計算を行うプログラムを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 ); }

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

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

分数でのプログラムができているのなら…… 実数部と虚数部がそれぞれ分数になれば良いのですよね? なら、 typedef struct { int denominator; int numerator; }FRACTION; typedef struct { FRACTION real; /* 実数部分 */ FRACTION 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); } を 、 frac_add( FRACTION x, FRACTION y ) COMPLEX comp_add(COMPLEX x, COMPLEX y) { COMPLEX tmp; tmp.real = frac_add(x.real, y.real); /* 実数部分の和 */ tmp.imag = frac_add(x.imag, y.imag); /* 虚数部分の和 */ return (tmp); } でできあがり。 他の演算も同じ(ごめん、未確認)

Falry_taie
質問者

お礼

加減算は出来ました。 乗算と除算に少々手こずってはいますが、何とかなりそうです。 お手数おかけしました。ありがとうございます。

その他の回答 (4)

  • TT414
  • ベストアンサー率18% (72/384)
回答No.5

質問の回答ではありませんが、気になったので >printf( "(%f+j%f)*(%f+j%f)=(%3.1lf+j%3.1lf)\n", とありますが最初の4つは%fで後の2つが%lfになっているのはなぜですか? %lfはC99以前は未定義です、C99以降は使えますが100%無駄な指定です、%fを使いましょう。

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

ん, 基本的には組み合わせるだけです. あとはどこまで頑張るかの勝負で, たとえば「もうちょっとオーバーフローに頑健にする」ことはできますね. 現状だと (int が 32ビット長の場合) 1/65536+1/65536 がまともに計算できないはずです. ただ, 加減算はどうしようもないといえばどうしようもないんだよね.... 乗除算については, 「結果を正常に表すことができればかならず正しく計算できる」ように作れると思うんだけど....

Falry_taie
質問者

お礼

なるほど。参考になりました。

  • f272
  • ベストアンサー率46% (7998/17100)
回答No.2

それなら,「分数の形で複素数の四則演算のプログラム」ではなくて,まず「分数の形で実数の四則演算のプログラム」を作ってみたらどうかな。

Falry_taie
質問者

補足

あ、それなら以前組んだことが有ります。 それと上記のプログラムを組み合わせればいいんでしょうか? /* 2つの分数を使った四則演算 */ #include <stdio.h> #include <stdlib.h> typedef struct { int denominator; int numerator; }FRACTION; int gcd( int x, int y ) { if ( y == 0 ) { return ( x ); } else { return ( gcd( y,x % y ) ) ; } } FRACTION frac_reduce( FRACTION x ) { FRACTION tmp; int a,b,sign = 1; a = x.denominator; if ( b < 0 ) { b = -b; } tmp.denominator = x.denominator / gcd(a,b) * sign; tmp.numerator = x.numerator / gcd(a,b) * sign; return ( tmp ); } FRACTION frac_add( FRACTION x, FRACTION y ) { FRACTION tmp; tmp.denominator = x.denominator * y.denominator; tmp.numerator = x.numerator * y.denominator+y.numerator * x.denominator; return ( frac_reduce( tmp ) ); } FRACTION frac_sub( FRACTION x, FRACTION y ) { FRACTION tmp; tmp.denominator = x.denominator * y.denominator; tmp.numerator = x.numerator * y.denominator-y.numerator * x.denominator; return ( frac_reduce( tmp ) ); } FRACTION frac_mul( FRACTION x, FRACTION y ) { FRACTION tmp; tmp.denominator = x.denominator * y.denominator; tmp.numerator = x.numerator * y.numerator; return ( frac_reduce( tmp ) ); } FRACTION frac_div( FRACTION x, FRACTION y ) { FRACTION tmp; tmp.denominator = x.denominator * y.numerator; tmp.numerator = x.numerator * y.denominator; return ( frac_reduce( tmp ) ); } int main( int argc, char **argv ) { FRACTION a,b,c; a.numerator = atoi( argv[1] ); a.denominator = atoi( argv[2] ); b.numerator = atoi( argv[3] ); b.denominator = atoi( argv[4] ); c = frac_add( a,b ); printf( "%d/%d + %d/%d = %d/%d\n",a.numerator,a.denominator, b.numerator,b.denominator,c.numerator,c.denominator ); c = frac_sub( a,b ); printf( "%d/%d - %d/%d = %d/%d\n",a.numerator,a.denominator, b.numerator,b.denominator,c.numerator,c.denominator ); c = frac_mul( a,b ); printf( "%d/%d * %d/%d = %d/%d\n",a.numerator,a.denominator, b.numerator,b.denominator,c.numerator,c.denominator ); c = frac_div( a,b ); printf( "%d/%d / %d/%d = %d/%d\n",a.numerator,a.denominator, b.numerator,b.denominator,c.numerator,c.denominator ); return( 0 ); }

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

「分数の形で」とはどういうことでしょうか? 「こんな感じのことがしたい」というのを見せてください.

Falry_taie
質問者

補足

(a+jb)/(c+jd) + (e+jf)/(g+ji) という形です。

関連するQ&A

  • 複素数代入解(C言語)

    n次の実多項式に複素数を代入するプログラムを教えてください。 typedef struct{ double r; double i; }comp; /*複素数の和*/ comp c_add(comp a,comp b){ comp c; c.r = a.r + b.r; c.i = a.i + b.i; return(c); } /*複素数のべき乗*/ comp c_pow(comp a,int n){ comp c; int i; double tpr,tpi; c.r = a.r; c.i = a.i; for(i=1;i<n;i++){ tpr = c.r; tpi = c.i; c.r = tpr*a.r - tpi*a.i; c.i = tpr*a.i + tpi*a.r; } return(c); } を定義してから、 /*a[]は多項式の係数、nは多項式の次数、bは代入する複素数*/ comp c_poly_eval(double a[], int n, comp b){ int i; comp tmp={0.0,0.0}; for(i=n; i>=0; i--){ tmp = c_add(tmp, a[i]*c_pow(b,i)); } return(tmp); } を作ったのですがエラーが出てしまいます。 a[i]*c_pow(b,i)でn次の値を計算して、c_addにいれることで0次~n次までの和を求めようとしたのですが、何が違うのでしょうか?

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

    複素数の四則演算(a+biとc+diの四則演算)について、for文を用いて表示するプログラムについて、???の部分に何を入れたらよいかわからず、うまく実行することができません。和・差・積・商の計算種別を入れるみたいなのですが、何を入れたらいいのかわかりません。 #include <stdio.h> void fukuso(double a,double b,double c,double d,double *e,double *f,int keisan); int main(void) { double a=4, b=8, c=4, d=3, e, f; int i; for(i=1;i<5;i++){ fukuso(a,b,c,d,&e,&f,???); if(i==1) printf("和演算\n"); else if(i==2) printf("差演算\n"); else if(i==3) printf("積演算\n"); else printf("商演算\n"); printf("e=%f f=%f i\n",e,f); } return (0); } void fukuso(double a1,double b1,double a2,double b2,double *a3,double *b3,int keisan) { if(keisan==1){ *e=a+c; *f=a+c; } else if(keisan==2){ *e=a-c; *f=b-d; } else if(keisan==3){ *e=a*c-b*d; *f=a*d+c*b; } else{ *e=(a*c+b*d)/(c*c+d*d); *f=(-a*d+c*b)/(c*c+d*d); } }

  • C言語の演算について

    次のプログラムを実行したらどう出力されますか。 微妙な代入演算の違いが分からないので、教えていただけないでしょうか。 #include<stdio.h> void main (void) { int x = 5; int y = 8; int z = 3; int a,b,c,d,e,f; a = y == x + z; b = !x; c = x + y / z; d = x *=z - 1; e = --y / --z; f = y+++ % x++; printf("%d,%d,%d,%d,%d,%d\n",a,b,c,d,e,f); } できれば途中のトレースも書いていただけると助かります。 よろしくお願いします。

  • 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言語の演算について

    次のプログラムを実行したらどう出力されますか。 微妙な代入演算の違いが分からないので、教えていただけないでしょうか。 #include<stdio.h> void main (void) { int x = 5; int y = 8; int z = 3; int a,b,c,d,e,f; a = y == x + z; b = !x; c = x + y / z; d = x *=z - 1; e = --y / --z; f = y++ % x++; printf("%d,%d,%d,%d,%d,%d\n",a,b,c,d,e,f); } できれば途中のトレースも書いていただけると助かります。 よろしくお願いします。 なお、先ほど記述ミスがあるのにも関わらず投稿してしまいました…。 正しい記述はこちらの質問です。 大変失礼しました。 前の質問は削除可能になり次第、削除いたします。

  • Matlabによる複素数・・・

    Matlabでの複素数の実部・虚部成分の成分表示方法についての質問です。 例えば、 f=3+3*i fr=real(f) fi=imag(f) とするとそれぞれ実部成分と虚部成分が求められますが、複素数fが以下の様に任意の変数(a)を使うとうまくいきません・・・ syms a; f=a^2+i fr=real(f) fi=imag(f) 結果:fr =1/2*a^2+1/2*conj(a)^2 fi =-1/2*i*(a^2+2*i-conj(a)^2) うまく"fr=a^2,fi=1"と結果を表示するためにはどうしたらいいのでしょうか・・・ 分かる方、よろしくお願いいたします。

  • c言語

    c言語で写真の課題を出されたのですが自分のプログラムでは上手くいきません。どこが間違っているのか教えて欲しいです。 自分のプログラム #include<stdio.h> #include<math.h> int main(){ int i,j; double c,d,x,y,z; for(i=0;i<=360;i++){ c=10*cos(i*M_PI/180); d=10*sin(i*M_PI/180); if(c>=0 && d>=0){ for(j=0;j<=1000;j++){ x=0.001*j; y =x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } if(c<=0 && d>=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c<=0 && d<=0){ for(j=0;j<=1000;j++){ x=-0.001*j; y=x*d/c; z=1-x*x-(sqrt(-x)+y)*(sqrt(-x)+y); if(z<=0.0){break;} } } if(c>=0 && d<=0){ for(j=0;j<=1000;j++){ x=0.001*j; y=x*d/c; z=1-x*x-(sqrt(x)+y)*(sqrt(x)+y); if(z<=0.0){break;} } } printf("x=%lf y=%lf z=%lf\n",x,y,z); } return(0); }

  • 複素数の四則計算

    複素数の四則計算を構造体を使って実行させたいのですが、いまいち構造体のことを理解できていません。 以下の何が間違っているのでしょうか? コンパイルはできますがおそらく間違った値が出てしまっているようです。 #include <stdio.h> typedef struct{ float re, im; } COMPLEX; COMPLEX cal ( COMPLEX a, char c, COMPLEX b ) { COMPLEX d; switch (c) { case '+' : d.re = a.re + b.re; d.im = a.im + b.im; break; case '-' : d.re = a.re - b.re; d.im = a.im - b.im; break; case '*' : d.re = (a.re * b.re) - (a.im * b.im); d.im = (a.im * b.re) + (a.re * b.im); break; case '/' : d.re = (a.re * b.re + a.im * b.im) / ( pow(b.re,2) + pow(b.im,2) ); d.im = (a.im * b.re - a.re * b.im) / ( pow(b.re,2) + pow(b.im,2) ); break; default :puts("不適切な演算です。"); break; } return d; } int main(void) { COMPLEX a; COMPLEX b; printf("aの実数部を入力:"); scanf("%f",&a.re); printf("aの虚数部を入力:"); scanf("%f",&a.im); printf("bの実数部を入力:"); scanf("%f",&b.re); printf("bの虚数部を入力:"); scanf("%f",&b.im); printf("%f + (%f)*i\n",cal(a,'+',b)); printf("%f + (%f)*i\n",cal(a,'-',b)); printf("%f + (%f)*i\n",cal(a,'*',b)); printf("%f + (%f)*i\n",cal(a,'/',b)); } 以上です。 ちなみに、例えばcal(a,'+',b)とすると和が返るようにしなさいという指示がありました。 どなたか教えて頂けるとありがたいです…。

  • C言語の構造体の問題が分かりません

    以下のソースコードを使って次の2つの問題に答えよ。というものです。 #include<stdio.h> #include<math.h> struct cartes{ double x,y; /*x-axis,y-axis*/ }; struct polar{ double r,th; /*radius,theta*/ }; struct cartes p2c(struct polar a) { struct cartes d; d.x=a.r*cos(a.th); d.y=a.r*sin(a.th); return d; } struct polar c2p(struct cartes b) { struct polar e; e.r=sqrt(b.x*b.x+b.y*b.y); e.th=atan(b.y/b.x); return e; } void main(void) { struct cartes c; struct cartes c1={1,1},c2={1,1.7320508},c3={1.7320508,1}; struct polar p1,p2,p3; struct polar p={1.41421356,0.7853982}; p1=c2p(c1); p2=c2p(c2); p3=c2p(c3); c=p2c(p); printf("radius=%lf, theta=%lf(radians)\n",p.r,p.th); printf("x-axis=%lf, y-axis=%lf\n",c1.x,c1.y); printf("radius=%lf, theta=%lf(radians)\n",p2.r,p2.th); printf("x-axis=%lf, y-axis=%lf\n",c.x,c.y); } 1.2次元直行座標における2点の座標を与えられて、2点間の距離を求める関数を作り、正しく動作するようにせよ。 2.複素数を構造体として定義せよ。次に2つの複素数変数を受けてその和、差、積、商を求める関数を作り、正しく動作するようにせよ。 以上2つの問題についてソースコードを書いてご説明いただければ幸いです。

  • 連立方程式を解きたい(複素数)

    実際の式よりかなり簡略化してます。 |1-a・X|^2 / |1-y・X|^2 = e   ・・・(1) |1-b・X|^2 / |1-y・X|^2 = f   ・・・(2) |1-c・X|^2 / |1-y・X|^2 = g   ・・・(3) X     →複素数(求めたいパラメータ) a,b,c,y  →既知の複素数(測定値) e,f,g   →既知の実数  (測定値) ||      →絶対値記号 上記の工学系方程式を解きたいのですが、絶対値記号があったり パラメータが複素数だったりでちんぷんかんぷんです。 まず、方程式は3つも必要なんでしょうか? ニュートン法じゃないと解けないのでしょうか? あつかましいお願いですが、文系の私にも分かるように説明をお願いできませんでしょうか。 数学の自由な皆さん、よろしくお願いします。

専門家に質問してみよう