メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.459) あゆしゃVS裏目小僧 対決編  2004/06/09


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第459回 あゆしゃVS裏目小僧 対決編
 発行    2004年6月9日(水曜日)
 発行数   約2900

{magclick}
/*========================================================*/
 はじめに ( 決り文句 )
/*========================================================*/
・このメールマガジンはまぐまぐさんから発行しています。
・ジャンルは、マルチメディアのプログラム、C言語です。
・このメールマガジンは、横60文字で作成しています。
 また、インデントはすべて半角スペース4つで構成しています。
・ここで扱うプログラムは、C言語と半光年以内のものです。
・登録解除は、まぐまぐさんのホームページでお願いします。
・まぐまぐさんのバックナンバー(下欄参照)を活用して下さい。
・ここは私の復習の場です。内容は約1ヶ月内外に私が勉強した
 内容になっています。最新の技術があれば、へたれもあります。
・わかりやすさを優先させる為、たまに嘘があるかもしれません。
・セキュリティ突破のため、暗号化された単語があります。

/*========================================================*/
 ご挨拶
/*========================================================*/

 こんにちは。あゆしゃです。

 先日、株の売買ゲームに登録しました。

野村のバーチャル株式投資倶楽部
http://www2.nomura.co.jp/vstock/VirtualServlet?

 仮想のお金(初期値:100万円)と、実際の株式の状態を元に
資金を増やすゲームです。

 参加費は無料で、扱われる株式の値段は本物ですので、株の
お勉強に最適です。

 月曜日現在、998575円、第44657位です。

 まだ、買った株式の手数料が引かれているだけで、株価の上がり
下がりは含まれていません。

 上位の人は10億ぐらい。・・・がんばろっと。

{magclick}
/*========================================================*/
 今回のお題  << あゆしゃVS裏目小僧 対決編 >>
/*========================================================*/

 裏目さんのホームページにアクセスできなくなったので、変だと
思っていたのですが、調査の結果、

★環境によってアクセス拒否される

 という、気難しい(?)サーバでした。

 なぜ気難しいのか、その原因は、DNSの変更のためという補足を
いただきました。

現状 OK URL
http://banana235.maido3.com/~bs3179/urame/prog/ALGO.HTM

DNS 変更後 OK URL
http://www.tensyo.com/urame/prog/ALGO.HTM

/*========================================================*/

 改めまして、裏目さんのプログラムを紹介します。

#define U32 unsigned long 
#define U16 unsigned short 
#define S32   signed long 
#define S16   signed short 
unsigned isqrt(U32 x) 

    int sft=0; 
    U16 y,y0,y1,sum; 
    U32 x0=x; 
    if(x<2) return x; 
    while( 0<(S32)x){x<<=1L; sft++;};
    y1=(U16)(x>>16L); 
    y0=(~y1)&0xffff; 
    y=(y0*0x8000)>>16;          sum=y; 
    y=(y*y0)>>16; y=(y*0x4000)>>16;sum+=y;
    y=(y*y0)>>16; y=(y*0x8000)>>16;sum+=y; 
    y=(y*y0)>>16; y=(y* 40960)>>16;sum+=y;
    y=(y*y0)>>16; y=(y* 45875)>>16;sum+=y; 
    y=~sum; 
    y+= ( (S16)((x-(U32)y*(U32)y)>>16L))>>1; 
    if(sft&1) 
    { 
        sft>>=1; 
        y= (U16)((0x8000L+(U32)(y>>sft)*46341L)>>16L);
    }else { 
        sft>>=1; y= y>>sft; 
    }; 
    return y; 


(VC環境でコンパイルを通すため、多少修正しました)

 ループは最初の、桁数を叩き割る処理だけで、後は固定の計算の
ようです。

 計算回数は、見た目は少なそうです。

 計算の内容は、アルゴリズム独特のマジックワードがいっぱいで
良くわかりません。

/*========================================================*/

 早速ですが、前回紹介したプログラムの結果です。

1回目
UINT ays_sqrt( UINT )    0.185us / 1time err:0
   UINT isqrt( UINT )    0.656us / 1time err:483419

2回目
UINT ays_sqrt( UINT )    0.185us / 1time err:0
   UINT isqrt( UINT )    0.681us / 1time err:483419



★動作速度については、ays_sqrt の圧勝となりました!

★整合性については、ays_sqrt の圧勝となりました!

★トータルポイントにおいて、ays_sqrt の圧勝となりました!

★ばんざーい! ★ばんざーい! ★ばんざーい! ★ばんざー・

/*========================================================*/

 よかったよかったーー;(ほんのり)

 負けたら CXInt に入れたいけど、マジックワードが良くわから
ないのでどうやって謝ろうかと考えていたのですが、杞憂であった
ようです。

 世界最速なのだから、負けるはずがありませんよね!

 桁数が小さければ、とふと思いましたが、裏目さんのものは、
桁数を割ったあとの計算回数は同じなので、たいした違いはないで
しょう。

/*========================================================*/

 ちなみに裏目さんアルゴリズムの最大の敗因と思われるものは、
環境の変化です。

/*========================================================*/

 裏目さんのプログラムは、マイコンで動かすことを前提として
作られています。

 よって、マイコンが持つ掛け算の処理速度が、重要です。

 インテルの掛け算は、1クロックぐらいで処理されます。これは
足し算と変わりがありません。

 掛け算のアルゴリズムで紹介したとおり、掛け算は単純なので、
気合と根性と電圧があれば、物理的に実現できるのだそうです。

 しかしマイコン、それも昔のマイコンだと、int ( short ) の
掛け算で10クロックはかかると思います。

 32ビットの UINT はもっと遅いかもしれません。15ぐらい?

 そのような環境では、掛け算の回数がものを言いますので、

あゆしゃ法 16回
裏目小僧法 11回

 掛け算の回数だけを見れば、裏目さんのほうが勝りますので、
結果が逆転したかもしれません。

/*========================================================*/

 ちなみに、掛け算よりシフトのほうが速いという伝説を聞いた
ことがあるかと思いますが、現在においては、

★真っ赤なうそ

 という時代になりました。

 シフト数を16とした場合、掛け算の2倍の時間がかかります。

 もちろん、15や14といった中途半端(8の倍数ではない)な
値を指定した場合、もっと遅くなります。

 騙されてはいけません。

/*========================================================*/

 ソースコードの掲載とリンクについては、裏目小僧さんに了解を
いただいています。

{magclick}
/*========================================================*/
 さいごに
/*========================================================*/

 新C言語使いにおくるチョー基本講座 第5回。

y=(y*y0)>>16; y=(y* 40960)>>16;sum+=y;

 このように、ソースに直接かかれた数字のことを、

★リテラル値

 といいます。

 そして16はともかく40960といった、出所の分からない
マジックワードは、リテラル値で書いては駄目、というのが一般的
なコーディングのルールです。

 なぜかというと、もしもこれがオチャッピーにより、

y=(y*y0)>>16; y=(y* 40980)>>16;sum+=y;

 となっていたとしても、バグに気がつきにくいのです。

 そして数字のうち間違えは、結構あるものです。

 変数ならば、名前が違うとコンパイラが教えてくれますから安全
なのですが、

 数字が1文字違ってもコンパイルエラーになりませんし、そのま
ま、普通っぽく動いてしまうので、

 怖いものです。

 ではどうするかというと、マクロか定数を使います。

#define ISQRT_NUM40960 40960

const int ISQRT_NUM40960 = 40960;

 という感じでしょうか。

 マクロ名称や定数名称に、その定数の数字を表記するのは、
1つの安全策です。

 これなら、数字のうち間違いについて、コンパイルエラーが
発生して、安全です。

 ソースの見易さとデバッグのしやすさも向上します。

 逆に数字の部分がないと、「このマクロの値は何だっけ?」と、
デバッグ中に大騒ぎすることになります。

{magclick}
/*========================================================*/
 次回予告
/*========================================================*/

 次回は6月13日(金曜日)に、第460回をお送りします。
 お題は「平方根の残骸」

 あゆしゃ法を作るに当たり、いくつかの失敗作がありました。

 お楽しみに!

/*========================================================*/
 最後の決り文句
/*========================================================*/
 このメールマガジンは、まぐまぐさんから発行しています。
 このメールマガジンを解除したい場合は、まぐまぐさんをご利用
ください。このメルマガのまぐまぐアイディーは最後にあります。
 このメールマガジンには広告が挿入されていますか?
 このメールマガジンの内容に文面の引用はありませんか?
 めーらっくすの場合はめーらっくすの利用方に従ってください。
 このメールマガジンの内容の、転用、流用、宣伝、リンク、
目指せ億万長者!<仮想<夢想 なんて大歓迎です。

{magclick}
/*========================================================*/
 
/*========================================================*/

発行者 あゆしゃ

ホームページ::あゆしゃの世界
http://ayusya.hp.infoseek.co.jp/

ご意見・ご感想・ご質問メール
mailto:ayusya@flamenco.plala.or.jp

まぐまぐ::アイディー
0000020674

まぐまぐ::登録と解除
http://www.mag2.com/m/0000020674.htm

まぐまぐ::バックナンバー
http://jazz.tegami.com/backnumber/frame.cgi?id=0000020674

めーらっくす::アイディー
MM3E1AEE285AB4F

めーらっくす::登録と解除
http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F 

めーらっくす::バックナンバー★最近のものならこちらが便利★
http://www.mailux.com/mm_bno_list.php?mm_id=MM3E1AEE285AB4F

ブラウザの閉じるボタンで閉じてください。