昨日の続きです。
図のように円の面積Xと長方形の面積Yとが等しいとき、
αを求めよ。
机上の数学だけで、この解を導くには、かなりの時間を有することだろう。
そこで、コンピュータを使って同じ計算を値を変化させながら計算させて、必要な桁数の近似値を出すというのが一般的な方法だろう。
先の記事にて、半径rから、∠αを定め、円の面積と長方形の面積を求める方法は示しました。
というか、既に示された図は、Javscriptで繰り返し計算させて円の面積と長方形の面積は、
circ_area = 0.16509804815466397
rect_area = 0.16509804815466392
と小数点以下16桁まで等しい値になっています。
円は、Math.PI*r*r
長方形は、rect_w*rect_h
と、計算式が違うので、誤差まで等しくなるとは考えにくいということを肝に銘じておいてください。
do {
/* 処理 */
} while ( circ_area != rect_area );
のようなループにすると、永遠に等しくないので、無限ループしてしまいます。
さて、どのように近似していくかというと、二分法(にぶんほう)です。
とりあえず最大値と最小値を求め、その中間値を求め、円の面積と長方形の面積の大小関係で、中間値を新たな最大値にするのか最小値にするのかを決め、これを繰り返すことで近似させていくということになります。
rの最大値と最小値の初期値を決めなければなりません。
最大値は、α=0˚のときなので、
r_max = (2-Math.sqrt(2))/2;
最小値は、α=90˚のときなので、
r_min = 0;
二分法のループは、回数で終わらせることにします。
二分法なので、2進数で考えると、ビット数だけループさせればよく、浮動小数点で仮数部は64ビットもないので、64回も回せば十分だと考える。
do {
r = (r_max+r_min)/2;
a = Math.acos((-1-(1-r)*(1-r)+(Math.sqrt(2)+r)*(Math.sqrt(2)+r))/(2*(1-r)));
b = Math.acos((+1-(1-r)*(1-r)+(Math.sqrt(2)+r)*(Math.sqrt(2)+r))/(2*(Math.sqrt(2)+r)));
circ = Math.PI*r*r;
rect_h = (1-r)*Math.sin(a)-r;
rect_w = Math.sqrt(1-rect_h*rect_h)-Math.sqrt(2)+1;
rect = rect_h*rect_w;
if ( circ > rect ) {
r_max = r;
} else {
r_min = r;
}
count--;
} while ( count );
Javascriptで求まったαの値は、
α(rad)=0.7698009252343918
α(deg)=44.10634408119648
でした。
多倍長演算プログラムで小数点以下100桁まで求めると、
α(rad)=0.7698009252343920812241465495874665749240037080777187527362746502982629660716695662114180170908167166
α(deg)=44.1063440811964972175372138125954852186029017307973807992137056509605231619427099610214580846933961823
となりました。
ではでは