質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2984閲覧

C++ 計算結果がnanになる原因が分からない

tsukagon

総合スコア30

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2021/08/14 14:00

編集2021/08/16 01:25

お世話になっております。C++初学者です。
ガウス・ジョルダンの消去法を用いて3つの連立方程式を解くプログラムを書きました。
他の関数内から値を渡して連立方程式を解くプログラムです。
問題点
計算に使う値を他の関数内から参照渡しした場合は計算結果がすべてnanと表示されてしまいます。この場合、計算する前にどのような値を受け渡しているのか表示して確認出来ています。しかし同じ値を手入力出来るプログラムを書いた場合はきちんと計算値が表示出来ているようでどこに問題があるのか分かりません。どこに問題がありますでしょうか。

関数バージョン

void keisan(int &j,double &B1x,double &B2x, double &B3x, double &B4x,double &B1y,double &B2y,double &B3y,double &B4y,double &B1z,double &B2z,double &B3z,double &B4z,double &r1x,double &r2x,double &r3x,double &r4x,double &r1y,double &r2y,double &r3y,double &r4y,double &r1z,double &r2z,double &r3z,double &r4z){ struct DATA r1,r2,r3,r4,rg,dr1,dr2,dr3,dr4,B1,B2,B3,B4,Bg,dB1,dB2,dB3,dB4; **//計算に使う値を表示して確認 ** cout<<r1x<<" "<<r1y<<" "<<r1z<<" "<<B1x<<" "<<B1y<<" "<<B1z<<endl; cout<<r2x<<" "<<r2y<<" "<<r2z<<" "<<B2x<<" "<<B2y<<" "<<B2z<<endl; cout<<r3x<<" "<<r3y<<" "<<r3z<<" "<<B3x<<" "<<B3y<<" "<<B3z<<endl; cout<<r4x<<" "<<r4y<<" "<<r4z<<" "<<B4x<<" "<<B4y<<" "<<B4z<<endl; r1.x=r1x; r1.y=r1y; r1.z=r1z; r2.x=r2x; r2.y=r2y; r2.z=r2z; r3.x=r3x; r3.y=r3y; r3.z=r3z; r4.x=r4x; r4.y=r4y; r4.z=r4z; B1.x=B1x; B1.y=B1y; B1.z=B1z; B2.x=B2x; B2.y=B2y; B2.z=B2z; B3.x=B3x; B3.y=B3y; B3.z=B3z; B4.x=B4x; B4.y=B4y; B4.z=B4z; rg.x=(r1.x+r2.x+r3.x+r4.x)/4; rg.y=(r1.y+r2.y+r3.y+r4.y)/4; rg.z=(r1.z+r2.z+r3.z+r4.z)/4; Bg.x=(B1.x+B2.x+B3.x+B4.x)/(sqrt(B1.x*B1.x)+sqrt(B2.x*B2.x)+sqrt(B3.x*B3.x)+sqrt(B4.x*B4.x)); Bg.y=(B1.y+B2.y+B3.y+B4.y)/(sqrt(B1.y*B1.y)+sqrt(B2.y*B2.y)+sqrt(B3.y*B3.y)+sqrt(B4.y*B4.y)); Bg.z=(B1.z+B2.z+B3.z+B4.z)/(sqrt(B1.z*B1.z)+sqrt(B2.z*B2.z)+sqrt(B3.z*B3.z)+sqrt(B4.z*B4.z)); //δrを計算 dr1.x=r1.x-rg.x; dr1.y=r1.y-rg.y; dr1.z=r1.z-rg.z; dr2.x=r2.x-rg.x; dr2.y=r2.y-rg.y; dr2.z=r2.z-rg.z; dr3.x=r3.x-rg.x; dr3.y=r3.y-rg.y; dr3.z=r3.z-rg.z; dr4.x=r4.x-rg.x; dr4.y=r4.y-rg.y; dr4.z=r4.z-rg.z; //δBを計算 dB1.x=B1.x-Bg.x; dB1.y=B1.x-Bg.y; dB1.z=B1.x-Bg.z; dB2.x=B2.x-Bg.x; dB2.y=B2.x-Bg.y; dB2.z=B2.x-Bg.z; dB3.x=B3.x-Bg.x; dB3.y=B3.x-Bg.y; dB3.z=B3.x-Bg.z; dB4.x=B4.x-Bg.x; dB4.y=B4.x-Bg.y; dB4.z=B4.x-Bg.z; //二次元配列に値を入力 static double array1[N][N + 1] = { { dr1.x, dr1.y, dr1.z, dB1.x}, { dr2.x, dr2.y, dr2.z, dB2.x}, { dr3.x, dr3.y, dr3.z, dB3.x} }; static double array2[N][N + 1] = { { dr1.x, dr1.y, dr1.z, dB1.x}, { dr2.x, dr2.y, dr2.z, dB2.x}, { dr3.x, dr3.y, dr3.z, dB3.x} }; static double array3[N][N + 1] = { { dr1.x, dr1.y, dr1.z, dB1.x}, { dr2.x, dr2.y, dr2.z, dB2.x}, { dr3.x, dr3.y, dr3.z, dB3.x} }; double a,b,c,d,e,f,g,h,i; // 計算クラスインスタンス化 Calc objCalc1; // 連立方程式を解く(ガウスの消去法) auto result1=objCalc1.gaussCalc(array1); // 計算クラスインスタンス化 Calc objCalc2; //連立方程式を解く(2回目) auto result2=objCalc2.gaussCalc(array2); // 計算クラスインスタンス化 Calc objCalc3; //連立方程式を解く(3回目) auto result3=objCalc3.gaussCalc(array3); //∇BGの要素を表示 cout<<j*timeinterval<<"s"<<endl; cout<<"∇BG="<<endl; cout<<result1.return1<<result1.return2<<result1.return3<<endl; cout<<result2.return1<<result2.return2<<result2.return3<<endl; cout<<result3.return1<<result3.return2<<result3.return3<<endl; cout<<" "<<endl; } 別の関数{ keisan(j,B1x,B2x,B3x,B4x,B1y,B2y,B3y,B4y,B1z,B2z,B3z,B4z,r1x,r2x,r3x,r4x,r1y,r2y,r3y,r4y,r1z,r2z,r3z,r4z); }

計算結果(計算に使った値を表示している)

1.24557 0.5 2.23205 -0.50394 0.53184 -0.38844 1.24557 0.4 0.442265 0.041703 0.55299 0.03279 1.24557 0.6 0.442265 0.041703 0.55299 0.03279 1.40887 0.5 0.5 0.041703 0.55299 0.03279 1s ∇BG= -nan-nan-nan -nan-nan-nan -nan-nan-nan

手入力バージョン(文字数の都合で同じ部分は省略してます)

int main() { struct DATA r1,r2,r3,r4,rg,dr1,dr2,dr3,dr4,B1,B2,B3,B4,Bg,dB1,dB2,dB3,dB4; cout <<"r1.xを入力して下さい" << endl; cin >> r1.x; cout <<"r1.yを入力して下さい" << endl; cin >> r1.y; cout <<"r1.zを入力して下さい" << endl; cin >> r1.z; cout <<"r2.xを入力して下さい" << endl; cin >> r2.x; cout <<"r2.yを入力して下さい" << endl; cin >> r2.y; cout <<"r2.zを入力して下さい" << endl; cin >> r2.z; cout <<"r3.xを入力して下さい" << endl; cin >> r3.x; cout <<"r3.yを入力して下さい" << endl; cin >> r3.y; cout <<"r3.zを入力して下さい" << endl; cin >> r3.z; cout <<"r4.xを入力して下さい" << endl; cin >> r4.x; cout <<"r4.yを入力して下さい" << endl; cin >> r4.y; cout <<"r4.zを入力して下さい" << endl; cin >> r4.z; cout <<"B1.xを入力して下さい" << endl; cin >> B1.x; cout <<"B1.yを入力して下さい" << endl; cin >> B1.y; cout <<"B1.zを入力して下さい" << endl; cin >> B1.z; cout <<"B2.xを入力して下さい" << endl; cin >> B2.x; cout <<"B2.yを入力して下さい" << endl; cin >> B2.y; cout <<"B2.zを入力して下さい" << endl; cin >> B2.z; cout <<"B3.xを入力して下さい" << endl; cin >> B3.x; cout <<"B3.yを入力して下さい" << endl; cin >> B3.y; cout <<"B3.zを入力して下さい" << endl; cin >> B3.z; cout <<"B4.xを入力して下さい" << endl; cin >> B4.x; cout <<"B4.yを入力して下さい" << endl; cin >> B4.y; cout <<"B4.zを入力して下さい" << endl; cin >> B4.z; rg.x=(r1.x+r2.x+r3.x+r4.x)/4; rg.y=(r1.y+r2.y+r3.y+r4.y)/4; rg.z=(r1.z+r2.z+r3.z+r4.z)/4; Bg.x=(B1.x+B2.x+B3.x+B4.x)/(sqrt(B1.x*B1.x)+sqrt(B2.x*B2.x)+sqrt(B3.x*B3.x)+sqrt(B4.x*B4.x)); Bg.y=(B1.y+B2.y+B3.y+B4.y)/(sqrt(B1.y*B1.y)+sqrt(B2.y*B2.y)+sqrt(B3.y*B3.y)+sqrt(B4.y*B4.y)); Bg.z=(B1.z+B2.z+B3.z+B4.z)/(sqrt(B1.z*B1.z)+sqrt(B2.z*B2.z)+sqrt(B3.z*B3.z)+sqrt(B4.z*B4.z)); //δrを計算 dr1.x=r1.x-rg.x; dr1.y=r1.y-rg.y; dr1.z=r1.z-rg.z; dr2.x=r2.x-rg.x; dr2.y=r2.y-rg.y; dr2.z=r2.z-rg.z; dr3.x=r3.x-rg.x; dr3.y=r3.y-rg.y; dr3.z=r3.z-rg.z; dr4.x=r4.x-rg.x; dr4.y=r4.y-rg.y; dr4.z=r4.z-rg.z; //δBを計算 dB1.x=B1.x-Bg.x; dB1.y=B1.x-Bg.y; dB1.z=B1.x-Bg.z; dB2.x=B2.x-Bg.x; dB2.y=B2.x-Bg.y; dB2.z=B2.x-Bg.z; dB3.x=B3.x-Bg.x; dB3.y=B3.x-Bg.y; dB3.z=B3.x-Bg.z; dB4.x=B4.x-Bg.x; dB4.y=B4.x-Bg.y; dB4.z=B4.x-Bg.z; //二次元配列に値を入力 static double array1[N][N + 1] = { { dr1.x, dr1.y, dr1.z, dB1.x}, { dr2.x, dr2.y, dr2.z, dB2.x}, { dr3.x, dr3.y, dr3.z, dB3.x} }; static double array2[N][N + 1] = { { dr1.x, dr1.y, dr1.z, dB1.x}, { dr2.x, dr2.y, dr2.z, dB2.x}, { dr3.x, dr3.y, dr3.z, dB3.x} }; static double array3[N][N + 1] = { { dr1.x, dr1.y, dr1.z, dB1.x}, { dr2.x, dr2.y, dr2.z, dB2.x}, { dr3.x, dr3.y, dr3.z, dB3.x} }; try { double a,b,c,d,e,f,g,h,i; // 計算クラスインスタンス化 Calc objCalc1; // 連立方程式を解く(ガウスの消去法) auto result1=objCalc1.gaussCalc(array1); // 計算クラスインスタンス化 Calc objCalc2; //連立方程式を解く(2回目) auto result2=objCalc2.gaussCalc(array2); // 計算クラスインスタンス化 Calc objCalc3; //連立方程式を解く(3回目) auto result3=objCalc3.gaussCalc(array3); //∇BGの要素を表示 cout<<"∇BG="<<endl; cout<<result1.return1<<result1.return2<<result1.return3<<endl; cout<<result2.return1<<result2.return2<<result2.return3<<endl; cout<<result3.return1<<result3.return2<<result3.return3<<endl; } catch (...) { cout << "例外発生!" << endl; return -1; } // 正常終了 return 0; }

手入力の計算結果

r1.xを入力して下さい 1.24557 r1.yを入力して下さい 0.5 r1.zを入力して下さい 2.23205 r2.xを入力して下さい 1.24557 r2.yを入力して下さい 0.4 r2.zを入力して下さい 0.442265 r3.xを入力して下さい 1.24557 r3.yを入力して下さい 0.6 r3.zを入力して下さい 0.442265 r4.xを入力して下さい 1.40887 r4.yを入力して下さい 0.5 r4.zを入力して下さい 0.5 B1.xを入力して下さい -0.50394 B1.yを入力して下さい 0.53184 B1.zを入力して下さい -0.38844 B2.xを入力して下さい 0.041703 B2.yを入力して下さい 0.55299 B2.zを入力して下さい 0.03279 B3.xを入力して下さい 0.041703 B3.yを入力して下さい 0.55299 B3.zを入力して下さい 0.03279 B4.xを入力して下さい 0.041703 B4.yを入力して下さい 0.55299 B4.zを入力して下さい 0.03279 ∇BG= -12.3238-0-0.304865 -12.3238-0-0.304865 -12.3238-0-0.304865

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KoichiSugiyama

2021/08/14 17:19

引数を画面に出力して値を確認しているのにうまくいっていない、というのであれば、構造体DATAにちゃんと値が入っているか、計算結果がどこでおかしくなっているか、順番に表示させていけば簡単に問題が追及できると思います。その過程で単純なミスに気づくこともありますので、まずは順番に値を表示させた結果を追記してみてください。
actorbug

2021/08/14 18:34

struct DATA、N、Calc、timeintervalの定義がわからないので、動作検証をすることができません。 質問には、そのままコピペするだけでコンパイルできるコードを貼り付けてください。
thkana

2021/08/15 01:37

> 計算する前にどのような値を受け渡しているのか表示して確認 これを各変数に次々と適用していけばどこかで違いが出るはずで、違いが出るまで探せばよいだけではないのですか? 違いを見つけないまま省略されたソースはしばしば問題となる違いが切り捨てられてしまっているので、全くとは言いませんが参考にならないことも多いです。 ところで、sqrt(B1.x*B1.x)ってのは...?
tsukagon

2021/08/16 01:10

アドバイスありがとうございます。thkana様、Koich様のおっしゃる通り、どこで結果がおかしくなっているかさらにさかのぼって確認したところ配列に上手く数値が代入出来ていないようでした。今回の問題点としては、関数化したことによって上手くいかなくなったため原因は値の受け渡しが上手くいってないことだろうと決めつけてしまっていたことでした。経験として今後に活かします。
guest

回答1

0

自己解決

staticを使う必要のない場所(値が更新される関数内)で使っていたため配列に関数外で更新される数値が入らなくなってしまっていた。

変更前

static double array2[N][N + 1] = { { dr1.x, dr1.y, dr1.z, dB1.x}, { dr2.x, dr2.y, dr2.z, dB2.x}, { dr3.x, dr3.y, dr3.z, dB3.x} };

変更後

double array2[N][N + 1] = { { dr1.x, dr1.y, dr1.z, dB1.x}, { dr2.x, dr2.y, dr2.z, dB2.x}, { dr3.x, dr3.y, dr3.z, dB3.x} };

投稿2021/08/16 01:23

tsukagon

総合スコア30

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問