sqrt(平方根)の計算
math.dll - 永字八法の続きっちゃー続きかも。
NScripterネイティブで、平方根を求めるsqrtを実装してみた。
なんで「ネイティブ」にこだわるかと言えば、たとえばONscripterに移植とかを考えた場合、dllに頼っているとうまくいかないことが多いからだ。「うみねこのなく頃に」がONscripterやらMacやらでプレイできないのは、画面効果dllのせいなのはよく知られた話だ。
使い方
sqrt %result,%num
第一引数には結果を格納する数値変数を、第二引数には平方根を求めたい数値を入れる。
得られる結果は、端数切り捨てになった数値である。1000倍した結果が欲しければ、元の数値を1000000倍してからやってくださいな。(ただし、それであんまり大きな数値を指定すると、NScripterが扱えなくなってエラーになるけど)
もし、第二引数に0やマイナスの数値を指定すると、0が返されるようになる。
スクリプト
define節、game命令以上
mov %0,100 ; 適宜変更すること。 numalias sqrt_base,%0:inc %0 numalias sqrt_result,%0:inc %0 numalias sqrt_try,%0:inc %0 numalias sqrt_temp,%0:inc %0 defsub sqrt
game命令以下、start節以上
*sqrt getparam i%sqrt_result,%sqrt_base mov %%sqrt_result,0 ; 初期化 if %sqrt_base<1 return ; 0とかマイナスの数値はよう扱わんわ。 if %sqrt_base=1 mov %%sqrt_result,1:return ; 1なら1だよな。ショートカット mov %sqrt_try,1 mul %sqrt_try,2 if %sqrt_try<%sqrt_base skip -1 div %sqrt_try,2 ~ mov %sqrt_temp,%%sqrt_result+%sqrt_try mov %sqrt_temp,%sqrt_temp*%sqrt_temp notif %sqrt_temp>%sqrt_base add %%sqrt_result,%sqrt_try if %sqrt_temp=%sqrt_base return ; ショートカット if %sqrt_try=1 return ; 終了条件 div %sqrt_try,2 jumpb
仕組み
非常にナイーブな実装になっている。
基本的には、nに対する平方根を調べるのに、仮の平方根mを設定し、mを二乗してnになるかどうか(近似値かどうか)を調べ、そうでなければ仮の平方根mを増やし……と言うやり方である。
速度に差が出るとすれば、このmの設定、増やし方の部分の工夫であり、今回は2進数を使うことで最短回数で割り出せるようになった、はず。
追記
平方根 - Atelier de Muguet 制作記録でつっこまれたよアハハン。
ニュートン法は昔みつけて忘れてたー。
やっぱ数学はまじめに勉強せんとあかんなー。