C プログラミング 入門 第8回 — 乱数・数学ライブラリ — 早稲田大学 創造理工学部 –建築・経営・資源– 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 1 / 23 前回の復習 配列 宣言 添字演算子「[ ]」 添字の有効範囲 初期化 多次元配列 #define 定義と使用法 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 2 / 23 前回の復習:配列 配列(int 型の変数を 100 個用意する場合) /*配列宣言*/ int Data[100]; 同じ扱いの変数が複数必要なとき,配列を使う 一つ一つの変数は,通し番号 (添え字)をつけて区別 添字演算子「[ ]」を使い,中に番号を指定する 番号は 0 から始まり,100-1=99 で終わる. Data[0] から Data[99] までの 100 個の変数が用意される 代入に関しては,今までと同様 配列は宣言と同時に初期化することが可能 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 3 / 23 前回の復習:マクロ定義 #define マクロ定義 (#define 文字列 1 文字列 2) 文字列1を文字列2で置き換える #define SIZE 3 この行以降は, 「SIZE」と書くと「3」だと扱われる マクロ定義には注釈を書く(推奨) 定数に対して名前が与えられ,プログラムが読みやすい 慣習として,マクロ名は大文字で書く 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 4 / 23 第 7 回小レポート課題 問題:次のファイルを作成し,Course N@vi より提出せよ 配列 A[3][4] に以下のような数字を入れ,それを転置させたものを表示す るプログラムを作れ.表示は以下のようにする. A= 1 2 5 6 9 10 A^t= 1 5 2 6 3 7 4 8 3 4 7 8 11 12 9 10 11 12 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 5 / 23 第 7 回小レポートの解答例(tenchi.c) #include<stdio.h> #define gyou 3 #define retsu 4 int main(void){ int i,j; int A[gyou][retsu]; /* A[3][4] と宣言 */ for(i=0;i<gyou;i++){ for(j=0;j<retsu;j++){ A[i][j] = retsu*i + j + 1; } } printf("A=\n"); for(i=0;i<gyou;i++){ for(j=0;j<retsu;j++){ printf("%3d",A[i][j]); } printf("\n"); } . . . 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 /* 値の代入 */ /* A の表示 */ 6 / 23 第 7 回小レポートの解答例(tenchi.c) .. . printf("A^t=\n"); for(i=0;i<retsu;i++){ for(j=0;j<gyou;j++){ printf("%3d",A[j][i]); } printf("\n"); } return 0; /* A^t の表示 */ } 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 7 / 23 本日の目標 ヘッダファイルのインクルード(#include)を理解する. 擬似乱数が使える. #include 初期化 整数乱数 実数乱数 数学ライブラリが使える 数学関数・定数 コンパイル方法(gcc ファイル名 -lm) 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 8 / 23 ヘッダファイルのインクルード(#include) プログラムの先頭で「 #include<stdio.h>」と記述してきた printf 関数や scanf 関数を使用するためにインクルード(読み込み) していた C 言語には,関数を集めた標準ヘッダファイルが準備されている プログラム中で使用する関数に応じて,必要な標準ヘッダファイル をインクルードする必要がある 主な標準ヘッダファイルは次の通り: stdio.h: printf, scanf 等(入出力関数) stdlib.h: rand, srand, exit, malloc 等 math.h: exp, aqrt, sin, cos 等(数学関数) string.h: strcpy, strlen 等(文字列処理関数) time.h: time 等(時刻,日付に関する関数) 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 9 / 23 擬似乱数 プログラムで (擬似) 乱数を利用する 「(i∗83+12)%101」として,一見ランダムな点数を与えたが,もう 少し複雑な式を用いた乱数を使う ✓ 乱数とは ✏ それぞれの数字が同じ確率で現れるように並べられた数字の列 のことである C 言語のプログラムでは,rand 関数を使う.この関数は乱数を 計算で求めている.各数字が正確に同じ確率で現れることはな いので,擬似乱数とも呼ばれる ✒ rand 関数はある値を元に乱数を計算し,2 回目以降は前回の乱 数値を元に計算するので,最初のある値が同じであれば,同じ 乱数の列が現れる 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 ✑ 10 / 23 擬似乱数 使用方法:必要なヘッダファイルを include する #include <time.h> #include <stdlib.h> /* time 関数を使う場合に必要 */ /* これは必要 */ 現在時刻を使って乱数を初期化する srand((unsigned)time(NULL)); /* 乱数系列を初期化 */ 実行させる度に同じ乱数を得たい場合は,これを省略するか 「srand(56);」などと固定値を指定 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 11 / 23 擬似乱数(規則性がかなり残っている) 0∼RAND _ MAX の整数乱数を得る a = rand(); (RAND_MAX は, stdlib.h の中で 0x7fffffff と定義されている) 0以上1未満の実数乱数を得る a = rand()/ (RAND_MAX +1.0); 0以上 N 未満の整数乱数を得る a = (int) (rand()/(RAND_MAX +1.0)*N); 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 12 / 23 擬似乱数使用例 ✓ さいころの目(saikoro.c) ✏ #include <stdio.h> #include <time.h> #include <stdlib.h> int main(void){ int a; srand((unsigned) time(NULL)); a = (int) (rand()/(RAND_MAX+1.0)*6); printf("Result is %d. Yn", a+1); return 0; } ✒ ✑ → 0∼5までの乱数を作り,最後に1を足せばよい. 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 13 / 23 演習 課題1:今の運勢を表示するプログラムを作れ. 下の確率で右のメッセージを表示するプログラムを作れ. 確率 メッセージ 30 % Very lucky 60 % lucky 10 % Not lucky 何回も実行させて,だいたい上記確率で表示されることを確かめよ time() は 1970 年 1 月 1 日 0 時 0 分(標準時)からの経過秒数を返す ため,1 秒以内に何度も実行すると,同じ数字で乱数を初期化する ことになり,結果も同じになってしまう 結果を日ごとに変えたい場合は,次のようにする srand((unsigned)time(NULL)/(60*60*24)); 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 14 / 23 課題1のヒント #include,乱数の初期化を忘れずに 判定は if 文を使う(例えば) : if(a<0.3) else if(a<0.9) else 第 8 回— 乱数・数学ライブラリ — printf("...") printf("...") printf("...") C プログラミング 入門 15 / 23 数学ライブラリ プログラムで sin や log などの数学関数,π などの数学定数を利用す ることができる. 数学関数や数学定数を使うには 1 ヘッダファイルを include する #include <math.h> 2 「-lm」(エル・エム)とつけてコンパイル $ gcc ファイル名 -lm これを忘れると「:undefined reference to ∼」とエラー 3 プログラムの中で数学関数を使用する(10 の自然対数) a= log(10.0); 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 16 / 23 数学ライブラリ(参考) 数学関数 使用法 fabs(x) log(x) pow(x,y) floor(x) cos(x) sin(x) tan(x) atan2(y,x) sinh(x) 意味 絶対値 自然対数 xのy乗 (小数点以下)切り下げ cos sin tan arctan(y/x) sinh 使用法 exp(x) log10(x) sqrt(x) ceil(x) acos(x) asin(x) atan(x) cosh(x) tanh(x) 意味 指数 常用対数 平方根 切り上げ arccos arcsin arctan cosh tanh 数学定数 使用法 M_PI M_E 第 8 回— 乱数・数学ライブラリ — 意味 π e 使用法 M_SQRT2 M_LN10 C プログラミング 入門 意味 2の平方根 loge 10 17 / 23 演習 課題2:以下のプログラムを作成し実行せよ 0◦ ∼180◦ まで 10◦ ごとに sin(x) の値を表示するプログラム. 数学ライブラリの sin 関数は,入力値の単位がラジアン. 角度, sin(x) の値の順で表示させるようにする. x の値は角度をラジアンに変換した値. 表示例: ang=0, sin(0)=0.00 ang=10, sin(0.17)=0.17 ang=20, sin(?)=? .. . ang=180, sin(3.14)=0.00 π は数学定数 M PI として定義されている 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 18 / 23 課題2のヒント math.h を用いる 変数の定義:角度 x,ラジアン rad 繰り返しは,for 文か while 文: while(x<=180){ 実行させたい命令 } 角度 x からラジアン rad への変換: rad = x * M PI / 180.0; 表示は printf: printf("ang=%.0f, sin(%.2f)=%.2f Y n",x, rad, sin(rad)); コンパイルの際「-lm」を忘れずに 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 19 / 23 第 8 回小レポート レポート提出について 次のプログラムを作成せよ ソースファイルは「08-学生番号.c」とせよ タイトルは「第 8 回小レポート」とする 本文には(必要があれば)講義内容や成績に対する質問を書くこと 課題を提出するときには課題のソースファイルを添付せよ 提出期限:授業中に指示 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 20 / 23 第 8 回 小レポート 課題:乱数を用いて,定積分の値を近似的に求めよ. 0以上1未満の乱数 x, y を入力された回数だけ繰り返し, y < sin(πx) となった割合 r を計算する ∫ 1 2 この割合は, sin πx = に収束する π 0 求めた値 r を表示し,2/π との語差 (Error) を表示せよ 表示は以下のようにする: How many trials? 1000【Enter】 Result is 0.652000 (Error: -0.015380) 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 21 / 23 第 8 回 小レポート(ヒント) ヘッダファイルの include を忘れずに(time.h,stdlib.h,math.h) -lm で数学ライブラリをリンクするのを忘れずに (x, y) の座標にそれぞれに対して 0∼1 の乱数を対応させる (x, y) の組を乱数により N 回発生させると,1 × 1 の正方形の中に N 個の点をばらまくことに相当する 求めたい割合: 条件を満たした点の数 点の数 N 点の数のカウントは int 型で行うこと 割合を計算するときにキャスト演算子を忘れずに 1 0 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 1 22 / 23 第 8 回 小レポート(追加課題) 追加課題:乱数を用いて,以下を求めよ. 正方形とそれに内接する 4 分の 1 円 ( 扇形 )を考える.この正方 形の中にランダムに点を落としたとき,正方形内の点と円内に落ち た点との比を考え円周率を求めよ.表示は小レポート課題と同じよ うに,回数を入力し,結果と,円周率(M PI)との誤差を出力せよ. (できたら加点) ソースファイルは「08-02-学生番号.c」とせよ 第 8 回— 乱数・数学ライブラリ — C プログラミング 入門 23 / 23
© Copyright 2025 ExpyDoc