授業のための覚書
2点, を通る直線の公式:これは Lagrange 補間(Lagrangian interpolation*1)と呼ばれる計算技法である。この式は次のようにも書ける:
2点, を通る直線の公式:「直線の式」だからって、この計算式の応用範囲が「直線を描画する」といったグラフィックスだけに限られるわけではない。例えば、摂氏温度*2から華氏温度*3への換算にも使える。水の氷点が(0度C,32度F), 沸点が(100度C,212度F)なので摂氏温度がc度のときの華氏温度の値はになる。
ここで受験数学の答案のような「筆算にしばられた発想」だと、係数を整理してとまとめるところだが、プログラミングの世界では整理すべきでない。この換算をC言語コードで書くときは、次のように書くのがベター;
// マクロ, 関数形式マクロ #define Cfleeze (0.0) #define Cboil (100.0) #define Ffleeze (32.0) #define Fboil (212.0) #define tempC2tempF(tempC) (tempC - Cfleeze)/(Cboil - Cfleeze)*(Fboil - Ffleeze) + Ffleeze
// 定数, 関数 float tempC2tempF (float tempC) { const float Cfleeze = 0.0, Cboil = 100.0; const float Ffleeze = 32.0, Fboil = 212.0; tempF = (tempC - Cfleeze)/(Cboil - Cfleeze)*(Fboil - Ffleeze) + Ffleeze; return tempF; }
このコードならば「tempC=CfleezeのときにFfleeze」「tempC=CboilのときにFboil」の値を返す tempC の1次関数を計算していると分かる。ややこしい計算はコンピュータにやらせればよい。むしろ「何の計算をコンピュータにやらせているのかはっきり分かる」コードの方がベターである*4
演算数から考えると const を使って計算の定数を予め作っておいて*5、define で「インラインで計算」するのが早いかも:
// マクロ, 関数形式マクロ // tempC2tempF(tempC) = (tempC - Cfleeze)/(Cboil - Cfleeze) // *(Fboil - Ffleeze) + Ffleeze #define Cfleeze (0.0) #define Cboil (100.0) #define Ffleeze (32.0) #define Fboil (212.0) const float tempC2tempFCoeff = (Fboil - Ffleeze)/(Cboil - Cfleeze), tempC2tempFOffset = -(Cfleeze)*(Fboil - Ffleeze)/(Cboil - Cfleeze) + Ffleeze; #define tempC2tempF(tempC) ((tempC)*tempC2tempFCoeff + tempC2tempFOffset)
*4:プログラミングの世界では、いきなり数値をソースコードに書くことは「マジックナンバー」と呼ばれ、プログラムの可読性が悪くなるので避けるべきとされている。;マジックナンバー (プログラム) - Wikipedia;可読性 - Wikipedia
*5:変数名は長くなってもよいから、計算で使うデータの内容を表示した方がよい。変数名の長さは、実際のCPU上で動くマシン語には影響しない。