コンピュータ演習4 打ち切り誤差・情報落ち 有効数字 位取りの”0”を除いた意味のある数字です。 具体的には、 6.05 m・・・有効数字3桁 0.65 m・・・有効数字2桁 1.6 m ・・・有効数字2桁 1.60 m・・・有効数字3桁 などで、より有効数字をはっきりさせた表現は 0.65 =6.5×101 のように*.**×10**と表現したときの*.**で有効数 字の桁数が分かります。これが数字の精度となり ます。 加減算 23 gのお菓子を1.5 gの袋に詰めると全部で何gになるでしょう か。 23 g+1.5 g=24.5 g 答 24.5 g としてしまいがちですが、“23 g”ということは“22.7 g”かもしれ ないし、“23.1 g”かもしれません。もともとお菓子の方は小数 点以下の値はあやしいのですから、袋の方がいくら細かく測 定してあっても、答えも小数点以下は意味がありません。で すから、小数第1位を四捨五入して、 23 g+1.5 g=24.5 g 答 25 g 5 とするのが正しいのです。つまり加減の場合は、一番粗い (有効数字の末位が最高の)項で答えの有効数字がきまりま す。 乗除算 縦1.3 m、横2.12 mの長方形の面積はいくらでしょうか。 1.3 m×2.12 m=2.756 m2 答 2.756 m2 としたくなるかもしれませんが、縦の長さの小数点以下第2位は不明です。ですから 1.3? ×)2.12 ‐‐‐‐‐‐‐‐‐‐‐‐‐ 26? 13? 26? ‐‐‐‐‐‐‐‐‐‐‐‐‐ 2.7??? となって、答えの小数第2位以下は意味がないことがわかります。したがって、小数 第2位を四捨五入して 1.3 m×2.12 m=2.756 m2 答 2.8 m2 8 とするのが正しいのです。つまり乗除の場合、答えの有効数字の桁数は、各項の有 効数字のうち最小のものと同じになります。 打ち切り誤差 打ち切り誤差とは、本来無限に行われなけれ ばならない計算を有限の範囲の計算で済ませ ることによって生じる誤差のことである。 ●無限級数による計算 ●台形則による(積分)面積計算 など 打ち切り誤差(例) 計算機による数値微分( #include<stdio.h> #include<math.h> float f(float x); int main(void){ float a=3.141592654f/4.0f, h; for(h=2.0f; h > 1.0f/2048.0f; h/=2.0f ){ printf("h = %f, df = %f¥n", h,(0.5f*f(a+h)‐0.5f*f(a‐h))/h); } return 0; } float f(float x){ return cos(sin(x)); } ) 真の値:‐0.4593626849327 【実行結果】 h = 2.000000, df = 0.086948 h = 1.000000, df = ‐0.208975 h = 0.500000, df = ‐0.386740 h = 0.250000, df = ‐0.440534 h = 0.125000, df = ‐0.454613 h = 0.062500, df = ‐0.458172 h = 0.031250, df = ‐0.459065 h = 0.015625, df = ‐0.459290 h = 0.007813, df = ‐0.459347 h = 0.003906, df = ‐0.459358 h = 0.001953, df = ‐0.459366 h = 0.000977, df = ‐0.459351 続行するには何かキーを押してください . . . 打ち切り誤差(対策) • 倍精度(double)にして計算する。 • 打ち切る個数を多くする。 • 打ち切り誤差が起こるように見えて、実は情 報落ちにより正しい数値が得られていない場 合もあるので注意。 桁落ち 同じくらいの大きさの数の差をとると、有効桁数 が減少することを桁落ちという。桁落ちした数値 を用いてそのまま計算を行うと、それ以降の数 値の有効桁数は減少したままである。 1001 1000 31.6386 6桁 31.6228 6桁 0.0158 3桁 桁落ち(例) 2次方程式の解 #include<stdio.h> #include<math.h> 真の解: 2560.9953143217, 0.0046856782333387 int main(void){ float x1, x2, D; float a=1.0f, b=‐2561.0f, c=12.0f; D = b * b ‐4.0f * a * c; x1 = (‐b + sqrt(D))/2.0f/a; x2 = (‐b ‐ sqrt(D))/2.0f/a; printf("%d x^2 + (%d)x + (%d) = 0 の解は ¥n",(int)a,(int)b,(int)c); printf("x1=%f, x2=%f¥n",x1,x2); printf("である¥n"); return 0; } 【実行結果】 1 x^2 + (‐2561)x + (12) = 0 の解は x1=2560.995361, x2=0.004639 である 続行するには何かキーを押してください . . . 数字で計算すると・・・ 桁落ち! 解決法! 解と係数の関係を使い、大きい解から小さい解 を求める! を用いると 桁落ち! を用いると 桁落ち(対策) • 倍精度(double)で計算する。 • 引き算をしない(数式を変形し、引き算がでな いように工夫する)。 演習 1.例題の2次方程式の解を求めるプログラムを正しい解が求められるよう 修正しなさい(変数や定数等はfloat型で計算してください)。 2.微分の近似公式 を用いて の の値を求めよ (変数や定数等はfloat型で計算してください) 。 3. のとき、 の値を求めよ (変数や定数等はfloat型で計算してください)。
© Copyright 2024 ExpyDoc