アプリ版:「スタンプのみでお礼する」機能のリリースについて

下記に記載したプログラムは一定時間、時刻を周期Tで割った物を整数化する事で得た周期外時刻分を引いて周期内数値に変え、周期前半なら1後半なら-1を格納しているだけだそうです。
このプログラムを理解したいのですが、各行に説明が書いてないのでいまいちよくわかりません。
なので、どなたか各行に「//」を書いたのでその横にその行のソースの説明を書いて頂けませんか?


#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define rint(x) ((int)((x)+0.5))//
#define trunc(x) ((int)(x))//

int main(void){//

/* (1) definition */
double tstep = 0.01, last_time = 5.00;//
int max_step; max_step = rint(last_time/tstep);//
double i, REtime, time, *output = new double[max_step];//

output[max_step], time;//
double T = 1.0; /* wave cycle *//
int j=0, multi;//

/* (2) generating square wave */
// amplitude : 1
// time cycle : T = 1.0[sec]
// time step : 0.01[sec]
// last time : 5[sec]

for (time = 0.0; time < (last_time+tstep); time = time+tstep){//
i = time/T; multi = trunc(i);//
REtime = time - T*multi;//
if (REtime <= T/2.0)//
output[j] = 1;//
else//
output[j] = -1;//
j = j+1;//
}

/* (3) file out */

int t1;//
FILE *f1;//
f1 = fopen("square.csv","w");//
for(t1 = 0; t1 < 500; t1++)//
fprintf(f1,"%f,\n",output[t1]);//
fclose(f1);//

return 0;

}

A 回答 (1件)

説明を分かりやすくするため、時間の単位を「秒」とします。



#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define rint(x) ((int)((x)+0.5))//小数点以下四捨五入
#define trunc(x) ((int)(x))//小数点以下切り捨て

int main(void){//プログラムの開始

/* (1) definition */
// tstep・・・波形を記録する時間間隔
// last_time・・・記録終了の時間
// ⇒下の場合、0.01秒毎に5秒になるまで記録します。
double tstep = 0.01, last_time = 5.00;

// max_step・・・終了時間まで記録する為に必要なレコード数。
// 0.01秒毎に5秒間記録するから、500個のレコードを保存する事になります。
// ⇒「四捨五入」で整数化していますが、これに+1するか、あるいは「切り上げ」
//  の方がいいと思います。入れ物は大きいにこした事はないです。
int max_step; max_step = rint(last_time/tstep)+1; //←勝手に+1を追加しました。

// i・・・波数(1周期を1.0として、何周回ったか)
// REtime・・・単周期内の経過時刻(1周期経過するごとに0.0になる)
// time・・・記録開始からの経過時間
// output・・・記録を保存するバッファ
double i, REtime, time, *output = new double[max_step];

output[max_step], time;// いらない行です。

// T・・・1周期の時間
// j・・・何個記録したかのカウンタ
// multi・・・何周期進んだか(iの整数部)
double T = 1.0; /* wave cycle *//
int j=0, multi;//

/* (2) generating square wave */
// amplitude : 1
// time cycle : T = 1.0[sec]
// time step : 0.01[sec]
// last time : 5[sec]

// 0.0秒から5.0秒まで、0.01秒毎に記録していきます。
// ぴったり5.0秒の場合も記録したいので、5.01秒までループさせます。
for (time = 0.0; time < (last_time+tstep); time = time+tstep){
// i=現在の波数(1周期を1.0として、何周回ったか)
// multi=現在何周目か(iの整数部)
// T*multi=現在の周期に入った時間
// REtime=現在の周期に入ってからの経過時間
i = time/T; multi = trunc(i);
REtime = time - T*multi;

// 現在の周期に入ってからの経過時間が半周期以内なら、1を、
// そうでなければ-1をバッファに格納し、バッファの格納位置を1つ進める。
if (REtime <= T/2.0)
output[j] = 1;
else//
output[j] = -1;
j = j+1;
}

/* (3) file out */
int t1; // ループカウンタ
FILE *f1; // 保存するファイルのポインタ
f1 = fopen("square.csv","w");// ファイルを開きます。

// output[]に格納した値を1つずつファイルに保存します。
// ⇒個数を500としていますが、各パラメータが変更された場合に修正する必要があるので、
//  500の代わりに、jを使った方が良いです。
//  (jにはoutput[]に格納された数が入っています)
for(t1 = 0; t1 < j; t1++)//
fprintf(f1,"%f,\n",output[t1]);//
fclose(f1);//
delete[] output;// ※outputはdeleteしないといけません。
return 0;

}

last_timeやtstepの値を変更する場合は、
for (time = 0.0; time < (last_time+tstep); time = time+tstep)
でループする回数が、max_step の数値以下になっているかどうか注意が必要です。
微妙な場合は、とにかくmax_stepを大きめにとりましょう。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!