プログラムの結果がnanになってしまいます。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
saitou

プログラムの結果がnanになってしまいます。

#1

投稿記事 by saitou » 13年前

以下の計算プログラムを作成し、コンパイルはできたのですが、計算結果全てnanになってしまいます。
どこが間違っているのか、どなたかご教授いただけますか?

Cに関しては勉強してまだ2ヶ月足らずで、分からないことも多々あります。
どうかよろしくお願いします。

実行例
基底関数の各パラメーターを入力してください。
d1:1
d2:2
d3:3
da1:1
da2:2
da3:3
ex11=nan
ex12=nan
ex13=nan
ex21=nan
ex22=nan
ex23=nan
ex31=nan
ex32=nan
ex33=nan

コード:

// 電子間反発積分に関して
#include <stdio.h>
#include <math.h>


/*交換積分(電子間反発積分)のexint1関数(rs|tu)の定義*/
double exint1(double x, double y, double z, int n1, int n2)
{
 int i, j;
 double r, u;
 double p1 = x + y;
 double s1 = x*y/(x+y);
 double p2 = x + z;
 double s2 = x*z/(x+z);
 double s3 = y + z;
 double p3 = y*z/(y+z);
 double q = r + u;
 double t = r*u/(r+u);
 double PI = 3.1416;
 double Rab = 1.4144;
 double sum;
	
 int k, l;
	
 if(k = 1)
 r = x;
 else if(k = 2)
 r = y;
 else
 r = z;
 
	
 if(l = 1)
 u = x;
 else if(l = 2)
 u = y;
 else
 u = z;
 
 if(i == j) // ex11, ex22, ex33
 for(k = 1; k < 4; k++)
  {
  for(l = 1; l < 4; l++)
   {
    sum += sqrt(PI*PI*PI*PI*PI)/(x*q*sqrt(2*x+q))*exp(-(x/2+t)*Rab*Rab);
    return sum;
   }
  }

 else if(i == 1 && j == 2) // ex12
 for(k = 1; k < 4; k++)
  {
  for(l = 1; l < 4; l++)
   {
    sum += 2*sqrt(PI*PI*PI*PI*PI)/(p1*q*sqrt(p1+q))*exp(-(s1+t)*Rab*Rab);
	return sum;
   }
  }

 else if(i == 2 && j == 1) // ex21
 for(k = 1; k < 4; k++)
  {
  for(l = 1; l < 4; l++)
   {
    sum += 2*sqrt(PI*PI*PI*PI*PI)/(p1*q*sqrt(p1+q))*exp(-(s1+t)*Rab*Rab);
    return sum;
   }
  }

 else if(i == 1 && j == 3) // ex13
 for(k = 1; k < 4; k++)
  {
  for(l = 1; l < 4; l++)
   {
    sum += 2*sqrt(PI*PI*PI*PI*PI)/(p2*q*sqrt(p2+q))*exp(-(s2+t)*Rab*Rab);
    return sum;
   }
  }
 
 else if(i == 3 && j == 1) // ex31
 for(k = 1; k < 4; k++)
  {
  for(l = 1; l < 4; l++)
   {
    sum += 2*sqrt(PI*PI*PI*PI*PI)/(p2*q*sqrt(p2+q))*exp(-(s2+t)*Rab*Rab);
    return sum;
   }
  }
 
 else // ex23, ex32
 for(k = 1; k < 4; k++)
  {
  for(l = 1; l < 4; l++)
   {
    sum += 2*sqrt(PI*PI*PI*PI*PI)/(p3*q*sqrt(p3+q))*exp(-(s3+t)*Rab*Rab);
    return sum;
   }
  }

 return (0);
}

int main()
{
 double d1, d2, d3;         /*STO-3Gの短縮係数di*/
 double da1, da2, da3;      /*STO-3Gの短縮指数αi*/

/*値の入力*/
 printf("基底関数の各パラメーターを入力してください。\n");
 printf("d1:");  scanf("%lf", &d1);
 printf("d2:");  scanf("%lf", &d2);
 printf("d3:");  scanf("%lf", &d3);
 printf("da1:");  scanf("%lf", &da1);
 printf("da2:");  scanf("%lf", &da2);
 printf("da3:");  scanf("%lf", &da3);

/*計算結果*/
 printf("ex11=%.4f\n", exint1(da1, da2, da3, 1, 1));
 printf("ex12=%.4f\n", exint1(da1, da2, da3, 1, 2));
 printf("ex13=%.4f\n", exint1(da1, da2, da3, 1, 3));
 printf("ex21=%.4f\n", exint1(da1, da2, da3, 2, 1));
 printf("ex22=%.4f\n", exint1(da1, da2, da3, 2, 2));
 printf("ex23=%.4f\n", exint1(da1, da2, da3, 2, 3));
 printf("ex31=%.4f\n", exint1(da1, da2, da3, 3, 1));
 printf("ex32=%.4f\n", exint1(da1, da2, da3, 3, 2));
 printf("ex33=%.4f\n", exint1(da1, da2, da3, 3, 3));

 return (0);
}

box
記事: 2002
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#2

投稿記事 by box » 13年前

ぱっと見ですけど

>if(k = 1) // kと1とを比べていない。kに1を代入している。以下同様。
>else if(k = 2)
>if(l = 1)
>else if(l = 2)

このへんが正しくないんじゃないかなぁ、なんて思ったりしてます。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#3

投稿記事 by h2so5 » 13年前

exint1 関数内で初期化されていない変数の演算をしています。
初期値を代入しないと、中身がどんな数字になるか分からないので注意してください。

以下、コンパイラの警告:
prog.c:17: warning: ‘r’ is used uninitialized in this function
prog.c:17: warning: ‘u’ is used uninitialized in this function
prog.c:25: warning: ‘k’ is used uninitialized in this function
prog.c:33: warning: ‘l’ is used uninitialized in this function
prog.c:40: warning: ‘i’ is used uninitialized in this function
prog.c:40: warning: ‘j’ is used uninitialized in this function
prog.c:45: warning: ‘sum’ may be used uninitialized in this function

saitou

Re: プログラムの結果がnanになってしまいます。

#4

投稿記事 by saitou » 13年前

k==1等にしてみたのですが、結果は変わりませんでした...

saitou

Re: プログラムの結果がnanになってしまいます。

#5

投稿記事 by saitou » 13年前

h2so5 さんが書きました:exint1 関数内で初期化されていない変数の演算をしています。
初期値を代入しないと、中身がどんな数字になるか分からないので注意してください。

以下、コンパイラの警告:
prog.c:17: warning: ‘r’ is used uninitialized in this function
prog.c:17: warning: ‘u’ is used uninitialized in this function
prog.c:25: warning: ‘k’ is used uninitialized in this function
prog.c:33: warning: ‘l’ is used uninitialized in this function
prog.c:40: warning: ‘i’ is used uninitialized in this function
prog.c:40: warning: ‘j’ is used uninitialized in this function
prog.c:45: warning: ‘sum’ may be used uninitialized in this function
具体的にどのようにすれば、改善できるのでしょうか?
sum = 0; のようにすれば良いのでしょうか?

box
記事: 2002
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#6

投稿記事 by box » 13年前

h2so5さんの指摘の方が、深刻度が高いかも…。

ある変数を計算に使うからには、「その前に」何かの値を「明示的に」入れておかないとダメ、ってことです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#7

投稿記事 by h2so5 » 13年前

コード:

if(k = 1)
r = x;
else if(k = 2)
r = y;
else
r = z;
例えばこの部分ですが、
変数 k は何を表しているんでしょうか?

仮引数でもなく、宣言がされているだけで、代入されていないので
k が1か2かの判定などできません。

プログラムの設計自体がおかしいです。

box
記事: 2002
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#8

投稿記事 by box » 13年前

>sum = 0; のようにすれば良いのでしょうか?

sumは、そういうことです。
おそらく、何かの合計を入れようとしてるんでしょうから、まずはゼロでないとダメ、ってことです。
他の変数は、どんな意味を持ってるかよくわからないので、パス。

まあとにかく、関数内のstaticでないローカル変数は、定義しただけでは中身は「ゴミ」です。
特定の値(ゼロとか)が入っていることを期待してはダメ。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

saitou

Re: プログラムの結果がnanになってしまいます。

#9

投稿記事 by saitou » 13年前

h2so5 さんが書きました:

コード:

if(k = 1)
r = x;
else if(k = 2)
r = y;
else
r = z;
例えばこの部分ですが、
変数 k は何を表しているんでしょうか?

仮引数でもなく、宣言がされているだけで、代入されていないので
k が1か2かの判定などできません。

プログラムの設計自体がおかしいです。
以下の式を計算したいです。
ΣΣ(rs|tu)=ΣΣ1/(pq(p+q)^(1/2))exp(-(s+t)Rab) ※t,uに対してそれぞれ和を取る。
p,sの値はint n1, n2で指定した値をとり、その値からまず式の形を判断して、 int k,lにかんしてはt,uの和を1〜3まで取る指標にしました。(1〜3それぞれにda1,da2,da3の値が対応して、r,uにそれぞれの場合の数値を代入できるかなと思いました。)
p,q,r,sはコードで定義した通りです。

例えば、
ex11=ΣΣ(11|tu)に対応していて、
ex11=(11|11)+(11|12)+(11|13)+(11|21)+(11|22)+(11|23)+(11|31)+(11|32)+(11|33)
という風に9個の和でかかなければいけないので、for文でまとめて書こうと考えました。

ただ、良く理解してなく、めちゃくちゃなプログラムになってしまい申し訳ありません。
この式を見て、何かプログラム作成のアドバイスをいただけないでしょうか?

box
記事: 2002
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#10

投稿記事 by box » 13年前

一つずつつぶしていきましょうか。

> double r, u;

この時点で、rとuの値はゴミである(どんな値であるかはわからない)、というのは先に回答したとおりです。
この状態で、

> double q = r + u;
> double t = r*u/(r+u);

こういう計算をしても、qもtも中身はゴミである、ということは理解できますか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#11

投稿記事 by h2so5 » 13年前

私もおかしな所を列挙しますね。

double exint1(double x, double y, double z, int n1, int n2)
exint1は引数 n1,n2 を持っていますが、二つとも関数内で一度も使われていません。

つまり、
exint1(da1, da2, da3, 1, 1)
の最後の 1, 1 の部分は計算結果に全く影響を及ぼしません。
[hr]
そして、

printf("d1:"); scanf("%lf", &d1);
printf("d2:"); scanf("%lf", &d2);
printf("d3:"); scanf("%lf", &d3);

d1~d3に数値を代入していますが、これも全く使われていません。
使っているのはda1~da3 のみです。

saitou

Re: プログラムの結果がnanになってしまいます。

#12

投稿記事 by saitou » 13年前

box さんが書きました:一つずつつぶしていきましょうか。

> double r, u;

この時点で、rとuの値はゴミである(どんな値であるかはわからない)、というのは先に回答したとおりです。
この状態で、

> double q = r + u;
> double t = r*u/(r+u);

こういう計算をしても、qもtも中身はゴミである、ということは理解できますか?
理解できました!では、r,uの値に入力された値da1,da2,da3を、k、lのような指標を使い場合に分けて代入するとしたら、どのような方法を取れば良いのでしょうか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#13

投稿記事 by h2so5 » 13年前

saitou さんが書きました:a2,da3を、k、lのような指標を使い場合に分けて代入するとしたら、どのような方法を取れば良いのでしょうか?
分岐はsaitouさんの方法でいいと思いますが、k,lの数値が決まっていません。
k,lには何が入り、どの時点で代入がされるのですか?

また、i, j の数値も決まっていません。

saitou

Re: プログラムの結果がnanになってしまいます。

#14

投稿記事 by saitou » 13年前

h2so5 さんが書きました:私もおかしな所を列挙しますね。

double exint1(double x, double y, double z, int n1, int n2)
exint1は引数 n1,n2 を持っていますが、二つとも関数内で一度も使われていません。

つまり、
exint1(da1, da2, da3, 1, 1)
の最後の 1, 1 の部分は計算結果に全く影響を及ぼしません。
[hr]
そして、

printf("d1:"); scanf("%lf", &d1);
printf("d2:"); scanf("%lf", &d2);
printf("d3:"); scanf("%lf", &d3);

d1~d3に数値を代入していますが、これも全く使われていません。
使っているのはda1~da3 のみです。
では、int n1, n2をint i, jに変えて、関数内のint i,jを消せば、最後の1,1の部分は意味があるのでしょうか?
すみません、d1〜d3はこれからexの値にかける係数を計算するときに必要なので、今は関係ありません。
消してから投稿すべきでした。

saitou

Re: プログラムの結果がnanになってしまいます。

#15

投稿記事 by saitou » 13年前

h2so5 さんが書きました:
saitou さんが書きました:a2,da3を、k、lのような指標を使い場合に分けて代入するとしたら、どのような方法を取れば良いのでしょうか?
分岐はsaitouさんの方法でいいと思いますが、k,lの数値が決まっていません。
k,lには何が入り、どの時点で代入がされるのですか?

また、i, j の数値も決まっていません。
k,lにはそれぞれ1〜3の数字が入ります。全部のペアとしては、
(k,l)=(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(2,3),(3,1),(3,2),(3,3)
の9通りそれぞれの場合で式の計算を行い和を取ったものを最終的な値にしたいです。
式9個をそれぞれの場合に書くと、最終的に全部で81個の式が必要になるのでfor文の形になったのですが、、
k,lに具体的に数値を入れるとしたら、定義の際に、
int k = 3;
などとすれば良いということなのでしょうか?
良く理解できてないようで申し訳ありません。

よろしくお願いします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#16

投稿記事 by h2so5 » 13年前

確証は持てませんが、saitouさんはおそらく根本的な誤解をされています。

例えば、a , bという2つの変数があったとして、
数学で「c = a + b と定義する」と書くのと
プログラミングで「int c = a + b;」と書くのとでは全く意味が違うということは分かりますか?

数学ではcの数値は何かと言われれば、どのタイミングであってもその時点での a ,bの和ですが、
プログラミングでは、cの数値は定義した時点でのa ,bの和であって、
定義後に a,b の数値が更新されても c は変化しません。

c はa + bの定義時点での結果のみを保持し、a + bという式は保持していません。

saitouさんのコーディングを見ると、このような事が分かっていないような気がします。

saitou

Re: プログラムの結果がnanになってしまいます。

#17

投稿記事 by saitou » 13年前

h2so5 さんが書きました:確証は持てませんが、saitouさんはおそらく根本的な誤解をされています。

例えば、a , bという2つの変数があったとして、
数学で「c = a + b と定義する」と書くのと
プログラミングで「int c = a + b;」と書くのとでは全く意味が違うということは分かりますか?

数学ではcの数値は何かと言われれば、どのタイミングであってもその時点での a ,bの和ですが、
プログラミングでは、cの数値は定義した時点でのa ,bの和であって、
定義後に a,b の数値が更新されても c は変化しません。

c はa + bの定義時点での結果のみを保持し、a + bという式は保持していません。

saitouさんのコーディングを見ると、このような事が分かっていないような気がします。
そうだったんですか...申し訳ありません、理解不足です。
値を更新するにはどうすれば良いのでしょうか?
この考えが根本的にもう間違っているのでしょうか?

saitou

Re: プログラムの結果がnanになってしまいます。

#18

投稿記事 by saitou » 13年前

関数のfor文中のreturn sumを消して、関数の最後のreturn (0)を、return (sum)に変えたら一応値はでるようになりました。
しかし、ex11の値だけ、未だにnanです。また、ex23,ex32に関しても間違った値が計算されています。
この事が何か解決につながらないでしょうか?解らないなりに色々考えたのですが、未だ解決はできません。
助けてください。。。

アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#19

投稿記事 by h2so5 » 13年前

saitou さんが書きました: 値を更新するにはどうすれば良いのでしょうか?
その変数が必要になる直前に代入をしてください。
例えば、

コード:

for(k = 1; k < 4; k++)
    {
    for(l = 1; l < 4; l++)
    {

    if(k = 1)
        r = x;
    else if(k = 2)
        r = y;
    else
        r = z;


    if(l = 1)
        u = x;
    else if(l = 2)
        u = y;
    else
        u = z;

        q = r + u;
        sum += sqrt(PI*PI*PI*PI*PI)/(x*q*sqrt(2*x+q))*exp(-(x/2+t)*Rab*Rab);
        return sum;
    }
}

maru
記事: 150
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#20

投稿記事 by maru » 13年前

いいかげんに誰か指摘してもいいように思うんですが...
"="は代入ですので

コード:

    if(k = 1)
        r = x;
    else if(k = 2)
        r = y;
    else
        r = z;
上記コードは K=1 を判定し、その結果、真であるので常に r = x を実行します。
やりたいことは k の値を判定し、1, 2, その他で r に代入する変数を変えたいのだと思いますが、
それなら k = 1, k = 2 ではなく k == 1, k == 2 としなければなりません。

コード:

    if(k == 1)
        r = x;
    else if(k == 2)
        r = y;
    else
        r = z;
また、別の書き方としては

コード:

    switch (k)
    {
        case 1:
            r = x;
            break;
        case 2:
            r = y;
            break;
        default:
            r = z;
            break;
    }
と書くこともできます。

アバター
asd
記事: 319
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#21

投稿記事 by asd » 13年前

maru さんが書きました:いいかげんに誰か指摘してもいいように思うんですが...
横槍ですが指摘自体はNo.2でboxさんが指摘、No.4で質問者様が直した報告をしていますよ。
まぁその後の皆さんのコードでは=のままなのでそれを指摘しているということであればその通りだと思います。
Advanced Supporting Developer
無理やりこじつけ(ぉ

maru
記事: 150
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#22

投稿記事 by maru » 13年前

asd さんが書きました:
maru さんが書きました:いいかげんに誰か指摘してもいいように思うんですが...
横槍ですが指摘自体はNo.2でboxさんが指摘、No.4で質問者様が直した報告をしていますよ。
まぁその後の皆さんのコードでは=のままなのでそれを指摘しているということであればその通りだと思います。
失礼しました。完全に見逃していました。
でもNo.4で直しても結果が変わらないって報告があって、その後も = のままなのはいただけないですよね。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#23

投稿記事 by softya(ソフト屋) » 13年前

まず、ここら辺のソフトで基本的なことを理解されたほうが良いかも知れません。

「KSK C Animationの詳細情報 : Vector ソフトを探す!」
http://www.vector.co.jp/soft/win95/edu/ ... tml?site=n

[基本法則]
・基本的にifやforやwhileなど制御文がない限りプログラムの命令文は上から下へ1つづ順番に実行される。
・代入文は、その時点での右辺が計算され左辺に代入される。それ以後の右辺値の変更には影響されない。
もし再び値を変えたいなら別の命令文などで代入する必要がある。
・C言語の場合、条件式中でも代入が可能。==と=は意味がぜんぜん違う。
==は同じか比較するが、=は代入してしまう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
asd
記事: 319
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#24

投稿記事 by asd » 13年前

maru さんが書きました:
asd さんが書きました:
maru さんが書きました:いいかげんに誰か指摘してもいいように思うんですが...
横槍ですが指摘自体はNo.2でboxさんが指摘、No.4で質問者様が直した報告をしていますよ。
まぁその後の皆さんのコードでは=のままなのでそれを指摘しているということであればその通りだと思います。
失礼しました。完全に見逃していました。
でもNo.4で直しても結果が変わらないって報告があって、その後も = のままなのはいただけないですよね。
そうなのですよね^^;
なので「ここらで == に改めましょうよという意味でmaruさんの指摘を捉える」と。

蛇足ついでに代入と比較の間違いを減らす方法を。

固定値との比較をしたい場合、固定値を左辺に書くと、誤って代入の書式にした場合に
コンパイル時エラーになります。

コード:

if(1 == x)//1 = xと誤った場合、1に代入はできないのでコンパイラでエラーにしてくれる
それ以外にもsoftyaさんが指摘されている基本的なところから少しずつ見直していったほうがよさそうですね。
Advanced Supporting Developer
無理やりこじつけ(ぉ

maru
記事: 150
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#25

投稿記事 by maru » 13年前

asd さんが書きました:蛇足ついでに代入と比較の間違いを減らす方法を。

固定値との比較をしたい場合、固定値を左辺に書くと、誤って代入の書式にした場合に
コンパイル時エラーになります。

コード:

if(1 == x)//1 = xと誤った場合、1に代入はできないのでコンパイラでエラーにしてくれる
こんな古いテクニックを使わなくても最近のコンパイラはちゃんと警告を出してくれるので、わざわざ読みにくいコードを書く必要はありませんね。

saitou

Re: プログラムの結果がnanになってしまいます。

#26

投稿記事 by saitou » 13年前

コード:

double exint1(double x, double y, double z, double a, double b, double c, int i, int j)
{
 double xyz[] = {0, x, y, z};
 double abc[] = {0, a, b, c};
 double p = xyz[i] + xyz[j];
 double s = xyz[i]*xyz[j]/(xyz[i]+xyz[j]);
 int k, l;
 double PI = 3.1416;
 double Rab = 1.4144;
 double sum = 0;
	
	  
 for(k = 1; k < 4; k++){
    for(l = 1; l < 4; l++){
	sum += abc[k]*abc[l]*sqrt(sqrt(2*xyz[k]/PI))*sqrt(sqrt(2*xyz[l]/PI))*2*sqrt(PI*PI*PI*PI*PI)/
		(p*(xyz[k]+xyz[l])*sqrt(p+(xyz[k]+xyz[l])))*exp(-(s+(xyz[k]*xyz[l]/(xyz[k]+xyz[l])))*Rab*Rab);
    }
 }

 return (sum);
 
}

皆様の意見を参考にしつつ、自分の理解を本を読みながら訂正、関数部分を以上の様なコードに書き換えたら、正しい値が出るようになりました。皆様本当にご指導ありがとうございました。

box
記事: 2002
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#27

投稿記事 by box » 13年前

どうせなら全部のコードを見せてほしいなぁ、なんて思うのは私だけ?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

saitou

Re: プログラムの結果がnanになってしまいます。

#28

投稿記事 by saitou » 13年前

box さんが書きました:どうせなら全部のコードを見せてほしいなぁ、なんて思うのは私だけ?
すみません遅くなりました。こんな感じになりました。

コード:

// 電子間反発積分に関して
#include <stdio.h>
#include <math.h>
#include <stdlib.h>


/*交換積分(電子間反発積分)のexint1関数ΣΣNtNudtdu(rs|tu)の定義*/
double exint1(double x, double y, double z, int i, int j)
{
	double xyz[] = {0, x, y, z};
	double p = xyz[i] + xyz[j];
	double s = xyz[i]*xyz[j]/(xyz[i]+xyz[j]);
	int k, l;
	double PI = 3.1416;
	double Rab = 1.4144;
	double sum = 0;
	
	
	for(k = 1; k < 4; k++){
		for(l = 1; l < 4; l++){
			sum += sqrt(sqrt(2*xyz[k]/PI))*sqrt(sqrt(2*xyz[l]/PI))*2*sqrt(PI*PI*PI*PI*PI)/
			(p*(xyz[k]+xyz[l])*sqrt(p+(xyz[k]+xyz[l])))*exp(-(s+(xyz[k]*xyz[l]/(xyz[k]+xyz[l])))*Rab*Rab);
		}
	}
	
	return (sum);
	
}

int main()
{
	int i, j;
	double da1, da2, da3;
		
	
	/*値の入力*/
	printf("基底関数の各パラメーターを入力してください。\n");
	printf("da1:");  scanf("%lf", &da1);
	printf("da2:");  scanf("%lf", &da2);
	printf("da3:");  scanf("%lf", &da3);
	printf("\n");
	
	
	
	/*計算*/
	
	/*exijの結果*/
	for(i = 1; i < 4; i++){
		for(j = 1; j < 4; j++){
			printf("ex%d%d=%.4f\n", i, j, exint1(da1, da2, da3, i, j));
		}
	}
	
	printf("\n");
	
	
	
	return (0);
}

アバター
asd
記事: 319
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#29

投稿記事 by asd » 13年前

maru さんが書きました:
asd さんが書きました:蛇足ついでに代入と比較の間違いを減らす方法を。

固定値との比較をしたい場合、固定値を左辺に書くと、誤って代入の書式にした場合に
コンパイル時エラーになります。

コード:

if(1 == x)//1 = xと誤った場合、1に代入はできないのでコンパイラでエラーにしてくれる
こんな古いテクニックを使わなくても最近のコンパイラはちゃんと警告を出してくれるので、わざわざ読みにくいコードを書く必要はありませんね。
全否定ですか・・・。
試しにgcc バージョン 4.1.2 20080704 (Red Hat 4.1.2-48)で試したら特に警告は出ませんでした。
こんな古いテクニックの紹介で申し訳ない限りです。
Advanced Supporting Developer
無理やりこじつけ(ぉ

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#30

投稿記事 by softya(ソフト屋) » 13年前

いろんな環境を使っているとデフォルトではワーニングが出ない環境は結構有ります。
あと、別に私は読みづらく感じませんよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: プログラムの結果がnanになってしまいます。

#31

投稿記事 by ISLe » 13年前

リテラルと比較するときしか使えないですからね。
ひっくり返しても代入できてしまうときの主従関係はどうなるのでしょう。
すべての主従関係が統一されていなければ、個人的には読みづらいと感じます。

可読性を落とさずにコンパイルエラーにする方法もあります。

コード:

if (+x == 1) {} /* OK */
if (+x = 1) {} /* コンパイルエラー */

アバター
asd
記事: 319
登録日時: 13年前

Re: プログラムの結果がnanになってしまいます。

#32

投稿記事 by asd » 13年前

ISLe さんが書きました:リテラルと比較するときしか使えないですからね。
ひっくり返しても代入できてしまうときの主従関係はどうなるのでしょう。
すべての主従関係が統一されていなければ、個人的には読みづらいと感じます。

可読性を落とさずにコンパイルエラーにする方法もあります。

コード:

if (+x == 1) {} /* OK */
if (+x = 1) {} /* コンパイルエラー */
この方法であれば可読性を落とさずに済みますね。
勉強になります^^
Advanced Supporting Developer
無理やりこじつけ(ぉ

閉鎖

“C言語何でも質問掲示板” へ戻る