メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.462) 少数の読み込み  2004/06/16


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第462回 少数の読み込み
 発行    2004年6月16日(水曜日)
 発行数   約2900

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

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

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

 先日、とんでもない事件がおきました。

★またしてもムカデ騒動です。

 あゆしゃがいつものように、楽しくワンピースの夢を見ていた
ときのことです。

 左手の人差し指に、

★★★★★★★★★★ガサガサガサ!!★★★★★★★★★★

 という感触があり、飛び起きました。

 ゴキブリかと思い、周囲をみまわしたところ、

★殺気を感じて右を索敵、たんすの裏に入っていくムカデを発見!

★★近距離からキンチョール(無臭)で攻撃、命中、これを撃墜!

 しました。めでたしめでたし。

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

 ところがその日一日、ガサガサの感触が左手に残り、1日中、
麻痺したように力が入りませんでした。

 ムカデ、恐るべしです。

/*========================================================*/
 株日記
/*========================================================*/

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

★Ayusyaの成績
金曜日 1,002,444円です。(21,299番/91,327人中)
土曜日 1,001,669円です。(21,913番/91,794人中)
月曜日 1,000,001円です。(22,925番/92,591人中)
火曜日 1,001,661円です。(23,376番/93,123人中)

 ああ、じわじわと下がってくる・・・空が(<?)

 しかし今週は盛り返しますよ、あゆしゃは奥義ゴールデン買いを
理解しましたゆえ!

 ・・・株の基本なんですけどね。かっこいい名前ですよね。

{magclick}
/*========================================================*/
 今回のお題  << 少数の読み込み >>
/*========================================================*/

 CXInt10 を使って、文字列から数字を読み込む処理を作りまし
た。

 それと同じように、CXIntFloat などと称して、文字列から少数
を読み込む処理を作る必要があるのでしょうか?

 ありません。

 前回、電卓で少数の値を求める方法を紹介したとおり、

 文字列との相互変換処理と、掛け算と割り算があれば、

 少数変換は可能なのです。

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

 0xABCD.EF は、43981.93359375 です。

0xABCD = 43981

0xEF = 239

239 / 256 = 0.93359375 ということです。

 これの逆を行えば、10進数文字列からの読み込み処理ができま
す。

 つまり、

93359375 = 0x5908D0F

0x5908D0F * 256 = 23900000000

23900000000 / 100000000 = 239 = 0xEF

 はい、クリア〜。簡単ですね。

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

 割る 100000000 のゼロの数は、小数部のビット数と同じです。

 そして、少数の有効桁数と同じです。

 少数の桁数は、ビット数と同じなのです。

 なぜなら、右端の数字は必ず5であり、1ビット増えるごとに
XX25を延々と生み出していくからです。

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

 小数部の桁数は、全体の4分の1固定としましょうか。

enum { SIZE = 1024 };
enum { SMALL_SIZE = SIZE / 4 }; // バイトサイズ
enum { SMALL_BIT_SIZE = SMALL_SIZE * 8 }; // ビットサイズ
UCHAR m_buff[ SIZE ];

 という感じで定数を持っておき、

CXInt& CXInt::fromFloatString( CString st )
{
    int pos = st.Find( "." );
    if( pos > 0 ) {
        fromString( st.Left( pos ) ); // 整数部を取得
        shlByte( SMALL_SIZE ); // 小数部をあける
        CXInt a;
        st = st.Mid( pos + 1 );
        int len = st.GetLength();
        if( len > SMALL_BIT_SIZE )
            st = st.Left( SMALL_BIT_SIZE );
        else if( len < SMALL_BIT_SIZE )
            st += CString( '0', SMALL_BIT_SIZE - len );
        a.fromString( st );
        a.shlByte( SMALL_SIZE );
        a.div( CXInt().fromString(
            "1" + CString( '0', SMALL_BIT_SIZE ) ) );
        memcpy( m_buff, a.m_buff, SMALL_SIZE ); // 小数部に
    }
    else fromString( st );
    return *this;
}

 という感じでしょうか。
 小数点がない場合は普通の fromString 、
 ある場合は、

 整数部と小数部とで分けて、

 小数部は普通に文字列として読み込み、

        a.fromString( st );

 ビット数だけ左シフトして、

        a.shlByte( SMALL_SIZE );

 最後に100000・・・・・でドゴーン!と割るのです。

        a.div( CXInt().fromString(
            "1" + CString( '0', SMALL_BIT_SIZE ) ) );

 後は整数部と合体して、はいクリア〜。

        memcpy( m_buff, a.m_buff, SMALL_SIZE ); // 小数部に

 簡単ですね。

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

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

 整数は、小数を扱えません。

 しかし、整数で小数を扱う技があります。

 それが、固定小数点数を使用する方法です。

 float や double は、浮動小数点数というもので、小数点位置が
ころころと変わるタイプです。

 固定小数点数は浮動小数点数を真似して、小数点位置が変わらな
い少数を扱おう、という、悪あがきです。

 たとえば。

 ゲーム画面が横256ドット縦224ドット(スーファミ仕様)
だったとしましょう。

 そこに、以下のようなプログラムで画像を表示します。


int x = 256 / 2; // 画面中央
int y = 224 - 64; // 画面下、キャラ64ドット

int mx = 16; // 移動速度 右に16ドット
int my = -32; // 移動速度 上に32ドット

int gx = 0; // 横方向重力 なし
int gy = 4; // 縦方向重力 下に4ドット

for( ;; )
{
    x += mx, mx += gx;
    y += my, my += gy;
}

 放物線を計算するプログラムです、適当ですが。

 格闘ゲームの右上方向にジャンプするときのキャラの動きを
思い浮かべてください。

 そういう感じでうごくっぽいです。

 しかし。

 こういうものを動かすと、すごい、角ばった動きをします。

 計算は1秒に60回繰り返されます、スーファミなので。

 そんなに計算したら、すぐにジャンプが終わってしまいます。

 「ぴ」です。

 ゲームボーイ版スト2顔負けの、動きの悪さです。

 しかし。

double x = 256.0 / 2.0;

 という感じで浮動小数点数を使うのは、面白くありません。

 計算速度を早くしたいのです。

 っていういかスーファミに double なんて存在しません。

 そこで。

 ゲームの座標を、大きくします。

 実は、スーファミのゲーム座標は、1ドットと1ドットの間に
目に見えないドットが1つあるのです。

 つまり、正確な画面の大きさは512*448ドットでした、
ということです。

 それをプログラムに反映すると、

 次回に続く。

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

 次回は6月18日(金曜日)に、第462回をお送りします。
 お題は「少数へ変換」

 いっそのこと、LC で固定小数点数を扱うようにしましょう。

 そのためには少数の文字列の読み込みと、文字列への変換が
必要です。

 お楽しみに!

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

{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

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