[[FrontPage]] * 問題 [#i4104715] - 外部表現の問題 -- 2000年なのに19100年と表示。 -- 2000年なのに19100年と表示。(ググると楽しい。) -- '0' + n の文字コードを表示しようとして文字化け。「19:0年」とか。 - 内部表現の問題 -- 桁数オーバーで入りきらない。 - 大小判定の問題 -- 1999年<2000年だが、99年>00年 - 同一性判定の問題 -- 1900年と2000年が区別がつかない。 - 閏年(うるう年)の判定ミス - 閏秒の考慮漏れ(ほとんど影響はない) - 桁数オーバー -- 2桁しか桁がないのに100という数字が来る。 -- オーバーフローでエラー -- 00 と解釈(周回) - 周回問題 -- 99 の次が 00 になる。 -- 11111111 の次が 00000000 になる。(上位桁を切ってしまう。) - 符号問題 -- 01111111 (127) の次が 10000000 (-128) になる。(最上位ビットが符号。周回と類似。) -- 時間(間隔)を求める時、時刻間の減算をする必要がある。単純に比較すると符号の影響を受けることがある。 --- 2147483647 の次は -2147483648 になる。Windows の内部タイマー(1ms単位)が 32bit なのでこの問題の影響を受ける。(24.9日) - 演算によるオーバーフロー -- n倍にしたりした時に発生する可能性がある。(2004年問題) * 対策 [#cdcca9ba] *** 内部表現 [#x4a4605e] - 桁数を増やす。 - ウィンドウで時刻により解釈を変える。 -- 2049年の時に00年を見たら2000年と解釈 -- 2050年の時に00年を見たら2100年と解釈 *** 外部表現 [#ab195420] (すでに2000年超えたので余り気にする必要はないかも?) - 下2桁に依存していないか確認。 - 決め打ちしていないか確認。 *** 大小判定 [#h27ca998] - 時刻同士で直接大小判定するのではなく、減算して時間差を見る。 *** 安易な対策は逆に問題を起こす [#h7742f2c] - 符号付き32bit値を単純に符号なし32bit値で扱うと、時刻間減算が正しくなくなる。 -- 結果も符号なし値にするとまずい。 問題を簡単にするために8ビットで表現 符号なし8bitの場合 255(0xff) - 254(0xfe) = 1(0x01) 254(0xfe) - 255(0xff) = 255(0xff) 255(0xff) - 0(0x00) = 255(0xff) 0(0x00) - 255(0xff) = 1(0x01) 符号付8bitの場合 -1(0xff) - -2(0xfe) = 1(0x01) -2(0xfe) - -1(0xff) = -1(0xff) -1(0xff) - 0(0x00) = -1(0xff) 0(0x00) - -1(0xff) = 1(0x01) -128(0x80) - 127(0x7f) = 1(0x01) 127(0x7f) - -128(0x80) = -1(0xff) * 問題が起こる日とその原因 [#o53bf7e2] *** 24日問題(24.9日問題) [#e25ad5e2] - 1ms 単位で符号付き 32bit タイマーを使うと、24.9日で符号が反転してしまう。 *** 49日問題(49.7日問題) [#je8a2c17] - 1ms 単位で 32bit タイマーを使うと、49.7日で周回してしまう。 *** 西暦2000年問題 [#c7e41d9f] - 下2桁しか保存していないので、1900年と2000年が区別できない。 - オーバーフローする。 - 19100年とか表示される。 *** 西暦2000年閏年問題 [#y37574a9] - 400年ルールがあるため、2000年は閏年 - 「100年ルールのため、閏年ではない」と勘違いしているものがあった。 *** 西暦2004年問題 [#c5c4f682] - 1970年1月1日から数えた秒数が符号付き 31bit(!)で表現できる最大値をオーバーする。 - 0.5秒を計算するために、秒数を倍にした後に半分にした結果、おかしなことになった。 *** 西暦2004年閏年問題 [#yc5ee1f2] - 2000年の閏年対策でミスったのか、判定ミスがあったらしい。 *** 昭和100年問題(2025年問題) [#u6656c87] *** 西暦2038年問題 [#e1e71ac1] - 1970年1月1日から数えた秒数が符号付き 32bit で表現できる最大値をオーバーする。 *** 西暦xxx0年問題 [#j0b3b919] - 2010年、2020年、2030年、2040年… - 10年ごとのウィンドウ方式を使った場合に正しく判定できなくなる可能性あり。 *** 西暦2100年問題 [#ob878675] - 歴史は繰り返す。 *** 西暦2100年閏年問題 [#u546acba] - 100年ルールのため、閏年ではない。