nanの原因

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

nanの原因

#1

投稿記事 by いん » 2年前

c言語で積分するプログラムを作りましたが、sum1[j][k]+=f1[j][k],sum2[j][k]+=f2[j][k]を行った後にprintfでsum1とsum2を表示するとnanと出てきます。
わかる方いらっしゃいましたらご回答していただけると助かります。

コード:

 
#include <stdio.h> 
#include <math.h> 
#define C 5
 #define w  0 
#define v  0 
#define G  4 
main() {
   float n,c; // Nは巻数  
float ur,N;
  int  i,j,k;  
int ef[C];  
float a,b,t,dt,d,I;  
float p[C][C],f1[C][C][C],f2[C][C][C],sum[C][C][C],sum1[C][C][C],sum2[C][C][C],fy[C][C];  
float kensa1[C][C][C],kensa2[C][C][C],A[C][C][C];
  float pi,pi2;
    pi=3.14159265;
  ur=5000.;  
I=1.;    
a=4.;        // 半径の値  
n=500.;          //分割数
  c=0;          //左端の値  
d=3.141592653;     //右端の値  
dt=(d-c)/n;     //間隔
  N=100;    
pi2=(float) 2*pi;
  //初期化作業をこのfor文で開始する。 
for(i=v; i <=G ; i++){    
for(j=v; j <=G ; j++){
      for(k=0-v; k <=G ; k++){
        A[i][j][k]=0.;
        p[i][j]=0.;
        sum1[i][j][k]=0.;
        sum2[i][j][k]=0.;
        sum[i][j][k]=0.;
        kensa1[i][j][k]=0;
        kensa2[i][j][k]=0;
      }
    }
  } 


for(i=v; i <=G ; i++){
    for(j=v; j <=G ; j++){
      for(k=v; k <=G ; k++){
         for(t=c;t<=d;t+=dt){        
ef[j]=0;
        p[i-w][j-w]=sqrt(i*i+j*j);
        fy[C-w][C-w]= acos(i/p[i][j]);
        //B(r)のそれぞれのものを計算する
        //for(t=c;t<=d;t+=dt){                                                   
kensa1[i][j][k]= sqrt(p[i][j]*p[i][j]+a*a+k*k-2*p[i][j]*a*cos(t));
          kensa2[i][j][k]=kensa1[i][j][k] * kensa1[i][j][k];
                                                                                        
  
f1[i][j][k]=(ur*a*I*k/(2*pi))*cos(t)/(kensa1[i][j][k]*kensa2[i][j][k]);
                      f2[i][j][k]=(ur*a*I/(2*pi))*(a-p[i][j]*cos(t))/(kensa1[i][j][k]*kensa2[i][j] [k]);
                                   sum1[i][j][k]+=f1[i][j][k]*dt;
          sum2[i][j][k]+=f2[i][j][k]*dt;          
          //微小な数字を足す
        }
       }
    }  
}      for(i=0-v; i <=G ; i++){
    for(j=0-v; j <=G ; j++){
      for(k=0-v; k <=G ; k++){
                printf("%f %f  %d %f %d  %f  %f \n",p[i][j],fy[i][j],k,sum1[i][j][k],ef [j],kensa[i][j][k],sum2[i][j][k]);        
      }
    }  
} 
}


あんどーなつ

Re: nanの原因

#2

投稿記事 by あんどーなつ » 2年前

floatをdoubleに変更してみては。
float, doubleはそれぞれ32bit, 64bit不動点小数点型です。
NaNは0に近い数字で割ると発生します。変数の計算精度より細かい計算をしようとするからです。

box
記事: 1719
登録日時: 8年前

Re: nanの原因

#3

投稿記事 by box » 2年前

いん さんが書きました:c言語で積分するプログラムを作りましたが、sum1[j][k]+=f1[j][k],sum2[j][k]+=f2[j][k]を行った後にprintfでsum1とsum2を表示するとnanと出てきます。

とりあえず、そのグチャグチャな字下げを何とかしましょう。

いん さんが書きました:

コード:

                printf("%f %f  %d %f %d  %f  %f \n",p[i][j],fy[i][j],k,sum1[i][j][k],ef [j],kensa[i][j][k],sum2[i][j][k]);        
ここで、変数kensaの定義がないというコンパイルエラーが出ます。実行できません。
nanという結果が出てしまう(つまり、少なくともコンパイルは通る)コードを貼ってください。
実行できないコードと実行結果を見せられましても、いかんともしがたいです。

【字下げの例】あくまで、例です。これが絶対的なものではありません。自分ならこう書く、という程度のものです。

コード:

#include <stdio.h>
#include <math.h>

#define C (5)
#define w (0)
#define v (0)
#define G (4)

int main(void)
{
    float n, c; // Nは巻数
    float ur, N;
    int i, j, k;
    int ef[C];
    float a, b, t, dt, d, I;
    float p[C][C], f1[C][C][C], f2[C][C][C];
    float sum[C][C][C], sum1[C][C][C], sum2[C][C][C], fy[C][C];
    float kensa1[C][C][C], kensa2[C][C][C], A[C][C][C];
    float pi, pi2;

    pi  = 3.14159265;
    ur  = 5000.;
    I   = 1.;
    a   = 4.;               // 半径の値
    n   = 500.;             // 分割数
    c   = 0;                // 左端の値
    d   = 3.141592653;      // 右端の値
    dt  = (d - c) / n;      // 間隔
    N   = 100;
    pi2 = (float) 2 * pi;

    //初期化作業をこのfor文で開始する。
    for (i = v; i <= G; i++){
        for (j = v; j <= G; j++) {
            for (k = 0 - v; k <= G; k++) {
                A[i][j][k]      = 0.;
                p[i][j]         = 0.;
                sum1[i][j][k]   = 0.;
                sum2[i][j][k]   = 0.;
                sum[i][j][k]    = 0.;
                kensa1[i][j][k] = 0;
                kensa2[i][j][k] = 0;
            }
        }
    }

    for (i = v; i <= G; i++) {
        for (j = v; j <= G; j++) {
            for (k = v; k <= G; k++) {
                for (t = c; t <= d; t += dt) {
                    ef[j] = 0;
                    p[i-w][j-w]  = sqrt(i * i + j * j);
                    fy[C-w][C-w] = acos(i / p[i][j]);

                    //B(r)のそれぞれのものを計算する
                    //for(t=c;t<=d;t+=dt){
                    kensa1[i][j][k] = sqrt(p[i][j] * p[i][j] + a * a + k * k - 2 * p[i][j] * a * cos(t));
                    kensa2[i][j][k] = kensa1[i][j][k] * kensa1[i][j][k];
                    f1[i][j][k]     = (ur * a * I * k / (2 * pi)) * cos(t) / (kensa1[i][j][k] * kensa2[i][j][k]);
                    f2[i][j][k]     = (ur * a * I / (2 * pi)) * (a - p[i][j] * cos(t)) / (kensa1[i][j][k] * kensa2[i][j][k]);
                    sum1[i][j][k]  += f1[i][j][k] * dt;
                    sum2[i][j][k]  += f2[i][j][k] * dt;
                    //微小な数字を足す
                }
            }
        }
    }

    for (i = 0 - v; i <= G; i++) {
        for (j = 0 - v; j <= G; j++) {
            for(k = 0 - v; k <= G; k++) {
                printf("%f %f  %d %f %d  %f  %f \n", p[i][j], fy[i][j], k, sum1[i][j][k], ef[j], kensa[i][j][k], sum2[i][j][k]);
            }
        }
    }
    return 0;
}
最後に編集したユーザー box on 2016年10月26日(水) 15:31 [ 編集 3 回目 ]
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

あんどーなつ

Re: nanの原因

#4

投稿記事 by あんどーなつ » 2年前

不動点小数点型 じゃなくて 浮動小数点型 でした。すみません

いん

Re: nanの原因

#5

投稿記事 by いん » 2年前

失礼しました。
訂正版です。

コード:

 
#include <stdio.h> 
#include <math.h> 
#define C 5
 #define w  0 
#define v  0 
#define G  4 
main() {
   float n,c; // Nは巻数  
float ur,N;
  int  i,j,k;  
int ef[C];  
float a,b,t,dt,d,I;  
float p[C][C],f1[C][C][C],f2[C][C][C],sum[C][C][C],sum1[C][C][C],sum2[C][C][C],fy[C][C];  
float kensa1[C][C][C],kensa2[C][C][C],A[C][C][C];
  float pi,pi2;
    pi=3.14159265;
  ur=5000.;  
I=1.;    
a=4.;        // 半径の値  
n=500.;          //分割数
  c=0;          //左端の値  
d=3.141592653;     //右端の値  
dt=(d-c)/n;     //間隔
  N=100;    
pi2=(float) 2*pi;
  //初期化作業をこのfor文で開始する。 
for(i=v; i <=G ; i++){    
  for(j=v; j <=G ; j++){
      for(k=v; k <=G ; k++){
        A[i][j][k]=0.;
        p[i][j]=0.;
        sum1[i][j][k]=0.;
        sum2[i][j][k]=0.;
        sum[i][j][k]=0.;
        kensa1[i][j][k]=0;
        kensa2[i][j][k]=0;
      }
    }
  } 


for(i=v; i <=G ; i++){
    for(j=v; j <=G ; j++){
      for(k=v; k <=G ; k++){
         for(t=c;t<=d;t+=dt){        
ef[j]=0;
        p[i][j]=sqrt(i*i+j*j);
        fy[C-w][C-w]= acos(i/p[i][j]);
        //B(r)のそれぞれのものを計算する
        //for(t=c;t<=d;t+=dt){                                                   
          kensa1[i][j][k]= sqrt(p[i][j]*p[i][j]+a*a+k*k-2*p[i][j]*a*cos(t));
          kensa2[i][j][k]=kensa1[i][j][k] * kensa1[i][j][k];
                                                                                        
  
          f1[i][j][k]=(ur*a*I*k/(2*pi))*cos(t)/(kensa1[i][j][k]*kensa2[i][j][k]);
          f2[i][j][k]=(ur*a*I/(2*pi))*(a-p[i][j]*cos(t))/(kensa1[i][j][k]*kensa2[i][j] [k]);
          sum1[i][j][k]+=f1[i][j][k]*dt;
          sum2[i][j][k]+=f2[i][j][k]*dt;          
          //微小な数字を足す
        }
       }
    }  
}      for(i=v; i <=G ; i++){
    for(j=v; j <=G ; j++){
      for(k=v; k <=G ; k++){
                printf("%f  %f \n",sum1[i][j][k],sum2[i][j][k]);        
      }
    }  
} 
}

あんどーなつ

Re: nanの原因

#6

投稿記事 by あんどーなつ » 2年前

? 間違って元のを貼った?

いん

Re: nanの原因

#7

投稿記事 by いん » 2年前

元のやつに書いてある最後のprintfを訂正したものです

あんどーなつ

Re: nanの原因

#8

投稿記事 by あんどーなつ » 2年前

いんさん

boxさんのいうには、

コード:

int main {
 int a = 0;
  int b = 1;
   return 0;
}
は、

コード:

int main {
  int a = 0;
  int b = 1;
  return 0;
}
にしたほうがいいと言っているね。それはいいにしても、f1[C][C][C]とか、3次元配列がでてきて物々しいけど
なんの積分をしようとしてたか説明しないと。あと、期待している出力をもし知っているなら伝えたほうがいい。
あと巻数ってなんだよww って話にもなる。

いん

Re: nanの原因

#9

投稿記事 by いん » 2年前

何度もすいません。
もう少しまとめてから再投稿しようと思います。
ありがとうございました。

閉鎖

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