メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.438) 大型計算機 平方根  2004/04/12


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第438回 大型計算機 平方根
 発行    2004年4月12日(月曜日)
 発行数   約2900

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

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

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

 少し時間が空いてしまいました。

 別に、ドdラrクエをやっていたわけでは、まったくそうです。

 やっと、大神殿にたどり着きました。遅いですが。

 それから、スーフfァミ版のカkジノ必勝法が使えないなぁと
思いつつ、インターネットで調べてみると、

 ・・・やっぱり存在するのですね。おかげでメタル剣をゲット
できました。

{magclick}
/*========================================================*/
 今回のお題  << 大型計算機 平方根 >>
/*========================================================*/

 前回までで、平方根を作るのに必要な関数を作りました。

class CXInt;

enum { SIZE = 1024; }

UCHAR m_buff[ SIZE ];

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

CXInt& add( CXInt& a );
CXInt& sub( CXInt& a );
CXInt& mul( CXInt& b );
CXInt& div( CXInt& b );
CXInt& shl( void );
CXInt& shr( void );
int cmp( CXInt& b );
CXInt& CXInt();
int getBit( int pos );
CXInt& setBit( int pos, int d = 1 );

 話の都合上、setBitの引き数のビット状態はデフォルト1と
してみました。

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

 さて、平方根と参りましょう。

 まずは、UINTの平方根です。こんな感じでした。

UINT ayu_sqrt( UINT a );

UINT x;
if( a >= ( UINT )65535 * ( UINT )65535 ) return 65535;
if( a > 32768 * 32768 ) x = 32768 + 16384;
else x = 32768 - 16384;
for( chk = 8192; chk; chk >>= 1 ) {
if( a > chk * chk ) x += chk;
else x -= chk;
}
if( a > x * x ) x++;
if( a < x * x ) x--;
return x;

(あ、chkの定義がないじゃん)
(あ、chk * chkのところ、x * xの間違いだ・・・というか、
 実行確認をしたソースと違うじゃん!・・・ごめんなさい)

 これは最初の処理が例外化されていますので、すこし展開して
みましょう。

UINT x, chk;
if( a >= ( UINT )65535 * ( UINT )65535 ) return 65535;
x = 32768;
for( chk = 16384; chk; chk >>= 1 ) {
if( a > x * x ) x += chk;
else x -= chk;
}
if( a > x * x ) x++;
if( a < x * x ) x--;
return x;

 これにあわせて、CXInt版を作りましょう。

CXInt& sqrt( void );

CXInt a( *this ); // 自分を複製
int pos = SIZE * 8 / 2; // 限界値のビット位置

// 最初の比較(オーバーフローチェック)
clear.setBit( pos-- ).dec(); // x = 65535
if( a.cmp( copy().pow() ) >= 0 ) return *this; // ret 65535;

// 自分を初期化
clear().setBit( pos-- ); // x = 32768

// 2回目以降の比較
for( ; pos; pos-- )
{
if( a.cmp( copy().pow() ) > 0 ) add( CXInt( pos ) );
else sub( CXInt( pos ) );
}
if( a.cmp( copy().pow() ) > 0 ) inc();
if( a.cmp( copy().pow() ) < 0 ) dec();
return *this;

 どうかな?

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

 そういえば、コピーコンストラクタを作っていませんね。

CXInt( CXInt& a );

memcpy( m_buff, a.m_buff, sizeof( m_buff ) );

 コピーするだけですが。

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

 そういえば、クリアー関数を作っていませんね。

CXInt& clear( void );

memset( m_buff, 0, sizeof( m_buff ) );
return *this;

 クリアーするだけですが。

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

 話の都合上、POWを作りましょう。

CXInt& pow( void );

return mul( copy() );

 自分を複製して自分自身と掛けるだけですが。

 ちなみにPOWはPOWERの略で、second power で二乗倍という
意味です。
 ここでは、second は省略されているということで。

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

 話の都合上、コピー関数を作りましょう。

CXInt copy( void );

return CXInt( *this );

 自分を複製するだけですが。

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

 そういえば、mul()などは、自分自身を引き数に指定されると
まずいですね。

 気に留めておきましょう。

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

 次回は4月14日(水曜日)に、第439回を送ります。
 お題は「大型計算機 16進数変換」

 ここまでくると、実行確認したい気分になりますね。

 しかしそれには、人間言葉に変換するツールが必要です。

 まずは簡単な、16進数文字列との変換から。

 お楽しみに!

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

 もとこ はともかく、あの顔でバトー・・・やだなぁ。

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

発行者 あゆしゃ

まぐまぐアイディー
0000020674

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

あゆしゃの世界
http://ayusya.hp.infoseek.co.jp/

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

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

めーらっくす <<過去ログがタイトル別になっています>>
http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F

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