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

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

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

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

Q&A

解決済

1回答

3745閲覧

ルンゲクッタ法でRC回路の出力関数を離散的にファイルに出力したい

SeyaTaniguchi

総合スコア10

C

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

0グッド

0クリップ

投稿2017/12/26 10:27

微分方程式を解くアルゴリズムである
ルンゲクッタ法の課題が出されました。
入力が周期1秒,最大値Eの矩形パルスということで
0.5秒周期でe(初期値10)を0⇒10⇒0⇒10⇒1とクロックさせたいのですが
ファイルに出力してみるとずっと10のままで,0にクロックしていません・・・

何処が原因か教えていただきたいです;;

ほかにも問題があればご指摘していただきたいです><

イメージ説明

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

double clock(double E){
if(E==10) return 0;
else return 10;
}

double dxdt(double x,int E){
double c = 0.001;
double r = 50000;
return (E-x)/(r*c);
}

// ルンゲクッタ法(初期条件x0, 区間[t0, tn])
double runge(double x0, double t0, double tn, int n)
{

FILE *output; FILE *output1;FILE *output2; output=fopen("output.txt","w"); output1=fopen("output1.txt","w"); output2=fopen("output2.txt","w"); double i; double x, t, h, d1, d2, d3, d4,cnt,e; x = x0; t = t0; e = 10; cnt=0; h = 0.01; // 漸化式を計算 for ( i=1; i <= n ; i++){ if(cnt==0.500000){e=clock(e); cnt=0;} t = t0 + i*h; d1 = dxdt(x,e); d2 = dxdt(x + d1*h*0.5,e); d3 = dxdt(x + d2*h*0.5,e); d4 = dxdt(x + d3*h,e); cnt= cnt + h; x += (d1 + 2 * d2 + 2 * d3 + d4)*(h/6.0); fprintf(output,"%f\n",t); fprintf(output1,"%f\n",x); fprintf(output2,"%f\n",e); } return x;

}

int main(void)
{
runge(0, 0, 1000, 50000);
return 0;
}

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

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

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

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

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

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

guest

回答1

0

ベストアンサー

計算機の浮動小数点数は内部が二進数表現になっており、またdoubleですと通常仮数が53bit程度ということで当然ながら無限の精度はありません。よって二進数で循環小数になるような数値は正確に表せない(常に誤差を含む)という点を知っておく必要があります。

本件でいえば0.01は循環小数になるので0.01 * 50は0.5に正確には一致しないと考えるべきです。一般に==で等値判定するなら整数を用いるべきです。0.01を50回加算したら0.5になると考えるのではなく1を50回加算して50かどうか判定するように頭を切り替えないといけないんですね。

本件は計算機プログラミングで「数学の世界と矛盾するためにわかっていないと大変混乱する」代表的な例の一つですが、他にもありますよね・・・

C

1int i = 2147483647; 2while (i > 0) { 3 i++; 4} 5// なぜか無限ループにならない・・・

投稿2017/12/26 11:06

KSwordOfHaste

総合スコア18394

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問