メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.580) 大型計算機 1.0.0.7  2005/06/29


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第580回 大型計算機 1.0.0.7
 発行    2005年6月29日(水曜日)
 発行数   約2600

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

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

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

 先日、「機械のコトバ」という本を購入しました。

 主に機械語についてのお話です。

 しかも「超ど級」の簡単内容です。

 ちょっと簡単すぎて、話が変な方向にずれていますが、まぁ、
いいでしょう。

 私は確認したかったのは、

★掛け算と割り算のアルゴリズム

 という項目です。

 これについては、以前ここで紹介しましたが、本当の(?)
アルゴリズムはいったいどうなのだろうと思ったのです。

 購入後、喜び勇んでその項目を確認したところ、

★どうというわけでもありませんでした。

 私が考えたものと同じです。

 本当にあんなものが「本当の」アルゴリズムなのでしょうか、
少々疑問です。

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

 先日、ベクターにて大型計算機をバージョンアップしました。

http://www.vector.co.jp/soft/winnt/personal/se353418.html

 今回のバージョンアップの理由としては、

「計算精度の向上、誤差を軽減」

 ということをReadMeに記載していますが、

 ・・・すみません、大嘘です。

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

 先日、

「1/100の答えがおかしい」

 という苦情をいただきました。

 そのような簡単な計算でミスがあるわけがないと笑ったところ、


1 /  100=0.015625


 うぉ、なんじゃこりゃぁ!?

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

 あせりながら冷静にステップ実行で処理を追ったところ、
比較処理の挙動がおかしいことに気が付きました。

 0x00000000 と、0x90000000 とで、0x00000000 の方が大きい、
というとんでもない判定をしていたのです。

// 算術比較
int CXInt::cmp( CXInt& b )
{
    int len1 = SIZE();
    int len2 = b.SIZE();
    int len = min( len1, len2 );
    UINT c = 0;
    len /= 4;
    if( len ) {
        UINT* pa = ( UINT* )m_buff + len - 1;
        UINT* pb = ( UINT* )b.m_buff + len - 1;
        do {
            c = *pa-- - *pb--;
        } while( ! c && --len );
    }
    return ( int )c;
}

 これが、実際の比較処理です。

 0と900〜であるとき、減算した結果が700〜となり、
それが正なので、左辺が大きい、と判断されていました。

 これによって、32ビットの最上位桁が異なる場合の大小判定が
おかしくなっていたようです。

 これを、このように書き換えました。

// 算術比較
int CXInt::cmp( CXInt& b )
{
    int len1 = SIZE();
    int len2 = b.SIZE();
    int len = min( len1, len2 );
    len /= 4;
    if( len ) {
        UINT* pa = ( UINT* )m_buff + len - 1;
        UINT* pb = ( UINT* )b.m_buff + len - 1;
        do {
            if( *pa < *pb ) return -1;
            if( *pa-- > *pb-- ) return 1;
        } while( --len );
    }
    return 0;
}

 大小判定を直接比較して、確実に動くようにしました。

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

 また、自己診断処理に、以下の処理を追加しました。

            CXInt a;
            CXInt b;
            a.fromString( "1" );
            b.fromString( "100" );
            a.div( b );
            CString ret = a.toFloatString();
            if( ret != "0.01" ) err = __LINE__;

 自己診断処理とは、大型計算機が行っている自動テストの
ことです。

 これに、今回の不具合の事例が発生しないということを入れて、
確実に動くことを確認しました。

 これで完璧ですね!

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

 いままで、微妙に誤差があるなぁと、時々思っていたのですが、
こんな根本的なことが原因だったとは、驚きです。

 何はともあれ、これで完璧ですね!?

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

 ちなみに、「式コピー」による、

1 /  100=0.015625

 このスペースの空き具合も、なんじゃこりゃぁ、という感じ
ですが。。。なんなんだろう。。

 あと、英語モードの「logic」のスペルが間違っているっぽい
ことに、いまさら気が付いたのですが。。。なんだろう。。

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

 次回は7月1日(金曜日)に、第581回をお送りします。
 お題は「加算表作成処理4」

 調子に乗って、もっともーっと巨大な加算表を作りましょう。

 お楽しみに!

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

{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

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