凪瀬 Blog
Programming SHOT BAR

目次

Blog 利用状況
  • 投稿数 - 260
  • 記事 - 0
  • コメント - 46616
  • トラックバック - 192
ニュース
広告
  • Java開発者募集中
  • 経歴不問
  • 腕に自信のある方
  • 富山市内
  • (株)凪瀬アーキテクツ
アクセサリ
  • あわせて読みたい
凪瀬悠輝(なぎせ ゆうき)
  • Java技術者
  • お茶好き。カクテル好き。
  • 所属は(株)凪瀬アーキテクツ
  • Twitter:@nagise

書庫

日記カテゴリ

 

本日はループカウンタのカクテルで。材料は
やまださまの0 ベースなんだけど……
επιστημηさまのどんだけ~?
囚人さまの0 ベース vs 1 ベース

3回の繰り返しを、1, 2, 3と数えるか、0, 1, 2と数えるか。 1から始まる1ベースと0から始まる0ベース。 日常生活では1ベースでモノを数えるのに、なぜプログラム言語では0ベースで数えるのでしょう? 以下は私が0ベースで数えたい理由です。

3回のループを0ベースと1ベースで書いて見ましょう。


// 0ベースでのforループ
for (int i=0; i<3; i++)

// 1ベースでのforループ
for (int i=1; i<=3; i++)

今、ループカウンタiはint型です。int型の2と3の間には何もないですから、"<"での比較と値を-1して"<="で比較しても結果は変わりません。 0, 1, 2 と数える0ベースよりも、1, 2, 3 と数える1ベースの方が人間の数え方に近い気がしますね。

1ベースが狂うとき

では、1ずつインクリメントするのではなく、10おきに30までカウントするという場合はどうでしょうか? つまり、10個ずつモノを数えるようなシチュエーションです。


// 0ベースで10ずつ増えるforループ
for (int i=0; i<30; i+=10)

// 1ベースで10ずつ増えるforループ
for (int i=1; i<=30; i+=10)

0ベースの場合、ループカウンタは 0, 10, 20, 30と増え、30となった時点で"30 < 30"が満たされなくなるので終了します。
1ベースの場合、ループカウンタは 1, 11, 21, 31と増え、30となった時点で"31 <= 30"が満たされなくなるので終了します。
どうでしょうか?不気味に感じませんか?本当にそんな数え方をしていますか?

人間の脳内では実は以下のように数えているのではないでしょうか?


do {
  ...
} while ((i += 10) <= 30);

そう、何かを行ってからループカウンタを増やしているのです。 10, 20, 30 と数えて、"30 < 30"となったところで数え終わっているのです。
そして、このループカウンタ周りの処理が繰り返しブロックの前にくると


// 0ベースで10ずつ増えるforループ
for (int i=0; i<30; i+=10) {
  ...
}
0ベースの記述になるわけです。
これが私の考えるプログラム言語で0ベースで数える理由のひとつです。

もうひとつの理由

もうひとつは、やや数学的な話になるのですが、0ベースでカウントし"<"で比較する方が綺麗に網羅できるからです。
intは離散的な(連続ではない飛び飛びの)値をとります。ですから、0と1の間には何もありません。 ですから 0 <= x < 3 という範囲の定め方をしても、1 <= x <= 3 という範囲の定め方をしても範囲は3なのです。
しかし、有限の幅を持つ値を扱うと前者のような範囲のとり方と、後者の範囲のとり方では大きさが変わってきます。 2007/8/10 <= x < 2007/8/13 は 24h * 3 = 3日分の時間がありますが、 2007/8/11 <= x <= 2007/8/13 は 24h * 2 = 2日分と3日目の0:00だけの時間しかないのです! (そしてこれは業務で日付演算をするときにやってしまいがちなバグなのです)

1 <= x <= 3といった範囲指定をしてもバグらないのはintなど整数型を用いた場合の例外なのですね。 数直線を引いたときに、常に左側(負の方)は境界値を含む(<=)、右側(正の方)は境界値を含まない(<)としておくと 連続的な値を持つ場合にも隙間を作ることなく処理できるのです。

いかがだったでしょうか。
納得がいかないという方は遠慮なくお申し出くださいませ。

投稿日時 : 2007年7月30日 23:08
コメント
  • # re: 数の数え方
    やまだ
    Posted @ 2007/08/01 1:23
    > 本当にそんな数え方をしていますか?
    これは for の条件の書き方に縛られているところがあるのではないかと思います。
    人間の脳内では「満たされなくなるので終了」ではなく「30を超えてしまったので終了」の方が自然ではないでしょうか。
    そう考えると "do ~ until (i += 10) > 30" で1ベースの方が良いという理屈も成り立つかも。

    #でも、私も until 文使った記憶はほとんどありませんが……。
  • # re: 数の数え方
    凪瀬
    Posted @ 2007/08/01 9:37
    判断文をブロックに対して後置にすると、1ずつインクリメントしているときは、ループカウンタはブロックを通過した回数を表すことになるのですが、10ずつカウントアップする際はちょっと意味合いが違うんですよね。

    プログラム的には条件判断は前置の方が、0回の繰り返しを処理できるので都合がよいです。後置の条件判断では最低でも1回は通過してしまいますが、大きさ0の配列といった存在を考えると使いどころが難しい。
    0かどうかの判断は前置、回数の判断は後置というのが人間的なのかもしれません。
  • # [画像処理](x1,y1,x2,y2) vs (x,y,width,height)
    myugaruの色々構想中・・・!
    Posted @ 2008/03/16 8:20
    [画像処理](x1,y1,x2,y2) vs (x,y,width,height)
  • # ujfEwrvAnvOkm
    http://catalinabiosolutions.com/
    Posted @ 2011/11/28 19:37
    See it for the first time!!...
  • # bhmTfSdETjLoVlnikmm
    http://paydayloansnocreditcheck.biz/
    Posted @ 2011/12/19 21:26
    Not bad post, leave it at my bookmarks!...
  • # aQSQLpQqWTCycwAqruF
    http://www.luckyvitamin.com/c-1418-alpha-lipoic-ac
    Posted @ 2012/01/07 3:30
    Not bad post, leave it at my bookmarks!...
  • # ブランド偽物
    jfynyc@hotmail.co.jp
    Posted @ 2022/10/16 4:27
    ヴィトンのマルチの白が大好きで集めています。
    2歳の子供がいるので、消毒ジェルや日焼け止めを入れるポーチを探していました。
    そういうものを入れて普段使いにしていると、
    どうせすぐに汚れるので新品でいいやと思いつつも、
    商品状態を心配していました。
    届いてみると、思っていたよりもだいぶきれいでした。
    梱包もヴィトンの箱や保存袋はありませんでしたが、プチプチで梱包してあり、丁寧だと思いました。
    また、機会があれば購入させていただきたいと思うショップさんでした。
    ありがとうございました。
    ブランド偽物 https://www.b2kopi.com/product/detail.aspx-id=11683.htm
タイトル
名前
Url
コメント