|
/*========================================================*/ <<<あゆしゃの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 |