プログラミング作業_3
超高精細度計算に挑戦してみました。

 カルキングは、300桁精度の数値で四則演算ができます。レジスターサイズが10進数で300桁です。 ここからはお遊びみたいなもので、実用上の用途はほとんどありません。 300桁の数倍の大きさの四則演算を準備しようというわけです。 こんな計算には興味が無い人は、このページはスキップしてください。

 このような作業を始めたきっかけは、各種の関数群をスクリプトを使って300桁で求めるることができるようになったので、平方根も、自分で組み直しました。 その検算のために、300桁*300桁を計算させれば、凡そ600桁で下位の300桁は切り捨てられます。 欲しい誤差部分を得ることができません。

 300桁の数値の自乗を誤差無しに求めようとするには、300桁のレジスタを半分以下の数値(ここでは、148桁にしました)のみで掛け算すれば、誤差なしで296桁の結果が得られます。後は筆算の掛け算の応用です。

 この計算が、下のようのなります。
 こんなの見たことが無いって?!

 ソウです。中段の点線で区切られた部分
 345×9=3105 と 345×8=2760
までは頭の中で目算による計算でした。

 10進1桁をレジスタ1つと考えれば、
たったこれだけでも沢山のレジスタが
必要です。

 このような掛け算は次の関数で計算できます。

 関数名はmultで、引数は配列の番号です。
 2次元配列aai,jを準備し、その中の1次元配列
p及びq番目の配列を掛け合わせて、r番目の
配列に結果を入れます。
 len は、pqr各々が使うレジスタの個数で、関数の
外で、len=10のように代入定義しておきます。

 これだけなら簡単ですが、最初のデータ入力、
次の計算のための後処理など、詳細をこのサイトで
全部を説明するには無理があります。

 この作業は、アセンブラの整数演算で長い桁数の計算を組む場合と同じです。 カルキングのような高級言語では、キャリーフラグなんていうものが無いので、300/2=150桁ではデータがあふれます。 少し減らして148桁にしました。

 筆者がe-book「関数グラフ入門」(ver2.0以降)の付録として「math」フォルダに追加したファイル「script6_6.clk」には、加減算とレジスタに納まる数値を乗数や除数にした乗除算、逆数計算を含め、1000桁レベルの計算が可能となるものにしてあります。

 上は、自作の300桁の関数(root4(x))を使った結果で、ルート(5*1010)を求めたものです。
 末尾部分に若干の誤差があることは、下の計算結果から分ります、
 上が計算を実行した結果の戻り値(300桁)で、下が、個々のレジスタに分配した目的の数値です。 以前他の方法で、計算した結果(1020桁)と比較して、全桁一致し、照合対象を手持ちしていない分を茶色にしてあります。 恐らくこの末尾までは正解です。

 1つの変数(レジスタ)にデータを入れることはできないので、上図のように配列aaの中にある、先頭部分のaa1の中のaa1〜aa10へ148桁ごとに区切って並べたのでした。

 上に書きましたように、自作の「平方根計算」を使って結果を求め、先ほどの mult(p,q,r)等を使って、実数値から1000桁以上の精度を持った結果が、簡単に得られます。(引数入力後、範囲選択して計算時間は、1秒未満です。手持ちのパソコンで)

 ここで、e-book「関数グラフ入門(ver1.20以降)」を入手された方のための解説です。添付ファイルが、まだ独りよがりで読みにくいかもしれません。

 ファイル「script6_6.clk」の解説

 最初は、平方根1000桁の計算方法です。ファイルを開き、[解説] を見てください。

 その直ぐ下に、左図のような記述があります。
上の表で示した部分のことです。本文の場合は、
見苦しいですが、「青い点線の枠」が付けて
あります。
 上の、[解説] に書いてあるように、引数を自分が
求めたい数値(ここでは2)に書き換えたところで、
点線をなぞるようにドラッグすると、右のように、
計算対象とする一式の計算式が選択されます。

 この状態で、メニューバーから、実行 再実行
を実施すれば、新しい引数を使った計算が実行
され、等号に続く部分は全て新しいデータで置
き換わります。(単に、F7(計算)だけでもOK。)
 実際は、rtest()関数を実行後、計算途中で
配列の中身を書き換え、それらを、改めて表示
するまでを、まとめて作業したわけです。
 新しいデータを保存したければ、ファイル 
名前を付けて保存で、自分の好きなように使え
ます。できれば、元のファイルは中身を変えずに
残してください。

 これらの関数群は、148桁の固定小数点のレジスターを数個並べた演算をするためのものになっています。右ページを見ると、下図のような定義部分があります。 i と j とは、配列定義要の変数定義で、aaは、10*10=100個からなる、配列です、10個で1組のレジスタを10本準備したわけです。

 slen=148 は、レジスタの中で、使われる標準桁数。len=10 は、1変数用のレジスタ個数で、j の最大値以下です。 この計算では、len個の最初が整数位で、次が小数点以下の最初の部分です。

 このファイルの中の関数群は殆んど、単純機能の関数です。 平方根の root4(x) は別格です。加算 add2(p,q) がp+qで、減算 sub2(p,q) はp-qです。len個のレジスタ列同士で演算します。 clr(n) は、n=0 即ち、n番目のレジスタ群の0クリアで、mov(p,q) は、p群をq群へ代入します。

 乗除算では、乗数や除数を変数サイズ(300桁以下)で処理する、rmlt(n,x)やrdiv(n,x)も準備しました。 この手の計算では、個々の数値が正の数でないとうまく行かない場合があるので、実数全体の処理用としては、追加しなくてはならない関数や機能が欲しい状態ですが、0から始めるのと較べれば、と考えて取り敢えずこの段階のものを提供しています。

 次のページ へ進む

 トップページ へ戻る

 前のページ へ戻る

SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送