コールスロー

世界というジグソーパズルの1ピース

かみやさんトリビュート(というかオマージュというか)

なにげないひとことが妙にツボにはまってクセになる「御紙屋流」(id:k_wizard)にちょっと長い遠隔コメント。

ペプシゴールドid:k_wizard:20061109)

写真がアップできないとのことなので、コンビニで実物を確認してしまいました。写真中央参照。
たしかにジンジャーエールかも。
あ、「血糖値が気になるおとしごろ」なので、味は未確認です。となりのPepsi NEXを買いました。

かみやさん危機一髪、あるいは"unsigned short"の恐怖(id:k_wizard:20061110)

発端

Q.かみやさんかみやさん、この近所にかみやさんは何人いるんですか?

A.65535人。

危険です。あとひとりでかみやさんが消滅してしまいます。

テストプログラム(countKamiyasan.c)
/******************************************************************
 * かみやさんをかぞえる -- unsigned short型をチェックする
 * 《前提条件》
 *   unsigned short(短精度符号なし整数)型の変数は多くのC言語処理系では
 *   16ビットで確保される。
 * 《考慮点》
 *   このため、この型で定義された変数に65535(最大値)を超えて加算すると
 *   桁あふれをおこし、計算結果が意図しないものとなる。このとき、
 *   C言語処理系ではこれをエラーとせず、処理を続行する。
 * 《このプログラムの動作》
 *   このプログラムではかみやさんの数をunsigned short型で定義し、
 *   初期値65535人にさらに1加算することでどのような現象がおこるのかを
 *   確認する。
 ******************************************************************/

/* 標準入出力の定義 */
#include 

/* 関数プロトタイプ */
void q_and_a(unsigned short no_of_kamiyasan);

/* かみやさんを数えるプログラム -- 本体 */
int main (){
    /* かみやさんの数を格納する変数をunsigned shortで定義 */
    unsigned short no_of_kamiyasan;
    /* かみやさんの数を初期設定する */
    no_of_kamiyasan = 65535;
    /* 最初のQ&A */
    q_and_a(no_of_kamiyasan);
    /* おしらせ */
    printf("かみやさんがもうひとりきました。\n\n");
    /* かみやさんに加算 */
    no_of_kamiyasan = no_of_kamiyasan + 1;
    /* 結果のQ&A */
    q_and_a(no_of_kamiyasan);

    return 0;

}

/* かみやさんの数を引数として受けとり、問答形式で出力 */
void q_and_a(unsigned short no_of_kamiyasan){
    printf("Q.かみやさんかみやさん、この近所にかみやさんは何人いるんですか?\n");
    printf("A.%d人。\n\n", no_of_kamiyasan);
}
コンパイル

ボーランドが無料で配布しているコンパイラを使用しました。

D:\tmp>bcc32 countKamiyasan.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
countkamiyasan.c:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

D:\tmp>
テスト結果
D:\tmp>countKamiyasan.exe
Q.かみやさんかみやさん、この近所にかみやさんは何人いるんですか?
A.65535人。

かみやさんがもうひとりきました。

Q.かみやさんかみやさん、この近所にかみやさんは何人いるんですか?
A.0人。

D:\tmp>
対策

かみやさんの増加にそなえて、"unsigned long"を使いましょう。

余談1

型変換でオーバーフローが発生し、ロケットが落っこちた例があるそうです。

格言1
ビットを惜しんでロケットを失う。
格言2
テストを惜しんでロケットを失う。
余談2

PCで書いたテスト済みプログラムをケータイで修正してしまったので、このコード自体は未確認です。バグがあったらごめんなさい。
テストしたいけどCコンパイラをもってない人は、"Borland freecommandlinetools"でググると吉かも。

追記

上記プログラムを修正しました。

修正点
  1. main関数の引数をけずった(T.Ryuchiさん助言感謝!!)
  2. コメントをふやした
  3. かみやさんの数をプリントするコードが冗長だったので関数化した
対策版の作成と実行結果

さらに、上記プログラムの変数定義を"unsigned long"に変更したものも作成しました(コードは省略)。実行結果はつぎの通りです。

D:\tmp>countKamiyasanOK
Q.かみやさんかみやさん、この近所にかみやさんは何人いるんですか?
A.65535人。

かみやさんがもうひとりきました。

Q.かみやさんかみやさん、この近所にかみやさんは何人いるんですか?
A.65536人。

D:\tmp>

このプログラムだと、かみやさんが4,294,967,295人まで増加しても正常に動作します(環境によってことなるため、実装前に調査が必要)。