今日のテーマ   日々改造 (^_^;)         
[記事リスト(ツリー表示)]  [ 返信 ]   [新着記事] [最新50] [ワード検索] [過去ログ]

タイトル SQRの計算式
投稿日: 2024/03/30(土) 15:58
投稿者konno
 番 号 11179    11178 番 としき さんへのコメント    コメント数 1

SQRの計算を自前で出来ないか検索してみました。
「本の虫」のサイトの「平方根のアルゴリズム 」
https://cpplover.blogspot.com/2010/11/blog-post_20.html

ここがわかりやすかったのでここから引用します。
-----------------------------------------------------------

ここで使うのは、バビロニア人の方法(Babylonian method)と呼ばれている、歴史あるアルゴリズムである。
この方法は、手動でも、プログラミングでも、非常に簡単に計算できる、大変便利で汎用的なアルゴリズムである。
しかも、速度もそれほど遅くない。 

double sqrt( double s )
{
    double x = s / 2.0 ; // Is there any better way to determine initial value?
    double last_x = 0.0 ; // the value one before the last step

    while ( x != last_x ) // until the difference is not significant
    { // apply Babylonian method step
        last_x = x ;
        x = (x + s / x) / 2.0 ;
    }
    
    return x ;
}

-----------------------------------------------------------

これを TurboBasic に置き換えたテストが

3000 ' SQR1.BAS
3010 'defdbl a-z
3020 screen 0
3030 cls
3040 input s
3050 x = s / 2.0  '; // Is there any better way to determine initial value?
3060 lastx = 0.0 '; // the value one before the last step
3070 '    while ( x != lastx ) '// until the difference is not significant
3080 'loop1:
3090        lastx = x 
3100        x = (x + s / x) / 2.0 
3110   if   x <> lastx  then 3080 'loop1
3120   print "SQR(";s;")=";x,lastx
3130   input a
3140 end

3020行をコメントにすれば N88BASIC でも動作します。
これをサブルーチンにして PRIME88.BAS に貼り付けて

1320 *START
1330 TM$=TIME$
1340 I=2:GOSUB *PRINT1
1350 FOR I=3 TO N
1360     IF INT(I/2)*2 = I THEN *EXIT2
1370         J=3
1375         s=I:gosub 3050:s=xx                '★
1380         WHILE (J<s) AND (INT(I/J)*J<>I)    '★
1390             J=J+1                          '★★
1400         WEND
1410         IF J>s THEN GOSUB *PRINT1          '★
1420     *EXIT2
1430 NEXT I
1440 I=I-1

この結果は
Number.10000	  0: 0:14   Prime Number = 1229 

おお、素数が合ってるし、時間が半分になりました。
SQR()関数を2回実行していたのをサブルーチン1回にしたのが効いたみたいです。

さらに、★★ のところを
1390             J=J+2                          '★★
このように +2 に変更した結果
Number.10000	  0: 0: 9   Prime Number = 1229 

おお、時間がさらに短縮して、FOR文のループとほぼ同じになりました。
ちなみに FOR文のソースにこのサブルーチンを組み込んだら
Number.10000	  0: 0:11   Prime Number = 1229 

2〜3秒遅くなりましたね。これが関数とサブルーチンの速度差と思われます。
思ったよりも差が無いなぁ、というのが感想です。(^^;

素数のネタはこの辺でしまいにしたいところですね。


- 返信フォーム (この記事に返信する場合は下記フォームから投稿して下さい)   [引用無し]
おなまえ 
Eメール 
タイトル 
メッセージ auto soft pre(図表、プログラム) ※折り返さずに改行を入れてね
 参照先 
 暗証キー (英数字で8文字以内)
 プレビュー          

- 以下のフォームから自分の投稿記事を修正・削除することができます -
   処理   記事No   暗証キー
    [ページトップへ] [管理用]