超高精細度計算に挑戦してみました。
カルキングは、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] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送 | ||