

## 質問

しばしば負のオーバーフローのことをアンダーフローと呼んでしまうという誤解がありますが、それに類似する話として質問があります。

とあるプログラムにおいて「日時」を扱っているのですが、一般的に時刻は hh:mm:ss で、`0 <= hh <= 23`, `0 <= mm <=
59`, `0 <= ss <= 59` のような範囲があると思います。最小の時刻は `00:00:00` で最大の時刻は `23:59:59`
というように。

このとき、便宜的にその範囲を超えて値を指定できる機能を作りたいとします。

例えば、`06:10:50` の30秒後を `06:10:80` と指定できるような機能です。この指定が行われたとき、時刻を `06:11:20`
に正規化したいという具合です。

今回質問したいのは、その実装についてではなく、用語についてです。

このように「秒」が 59
を超えていることを指して、「秒の値がオーバーフローしている場合」という表現は適切なのでしょうか。「秒が59を超えている場合」を指す適切な専門用語がないのかと思って質問させていただきました。

また同様に、`1970/09/01` のような日付があるとき、`1970/09/00` を `1970/08/31`
として扱う、というようなことがあると思いますが、これに対して「日の値がアンダーフローしている場合」という表現は適切なのでしょうか。これは不適切に思いますが、だからといって「日の値が負のオーバーフローが生じている場合」のように言うのもおかしいと思っています（`00`
は負ではないので）。

  * 時刻や日付が、通常の日時表記の値の範囲外になる場合のことを指す適切な用語があれば教えていただきたいです。
  * 前述のように、これらを「オーバーフロー」または「アンダーフロー」と表現するのが不適切であれば、それが如何に不適切であるか（誤用であるか）について説明していただきたいです。

そもそもオーバーフローという用語が何を指すかという話にも立ち入りそうですが、このような疑問を持っている私にアドバイスをいただければ幸いです。

## 背景

とあるプロジェクトで共同開発しているのですが、そのプロジェクトのドキュメントに別の方が「秒の値がオーバーフローしている場合」、「日の値がアンダーフローしている場合」のように記述していて、より適切な表現がないか気になったという背景があります。


CC BY-SA 4.0
2023-11-06T18:31:28.247
96694
2023-11-07T13:23:16.483
2023-11-07T02:20:26.280
51937
51937
question
専門用語
オーバーフロー、アンダーフローの用語の使い方と、それに類似する用語について


まあ普通に [c](/questions/tagged/c "'c' のタグが付いた質問を表示")
プログラマがオーバーフローアンダーフローというときは特定ビット数サイズの整数なり浮動小数点数なりにおいて  
オーバーフローは絶対値が大きい方向に表現できなくなった場合  
アンダーフローは絶対値が０方向に精度が失われる場合

カレンダーに関しては下記のようなプログラムを普通に書きますし、動作保証されているはずです。

[code]

    #include <stdio.h>
    #include <time.h>
    
    int main() {
        struct tm t1 = {
            50, 10, 6, /* 06:10:50 */
            30, 2-1,  2023-1900, /* 2023/Feb/30 */
            /* omit following member */
        };
        t1.tm_sec += 30;
        time_t t2 = mktime(&t1);
        printf("%s\n", ctime(&t2));
    }
    
[/code]

なので、これをオーバーフローとかアンダーフローとか呼ぶのは違和感があります。あえて言うなら「非正規表現」とか「非厳密表現」とでも言いましょうか。例えば
[java](/questions/tagged/java "'java' のタグが付いた質問を表示") の
[Calendar](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Calendar.html)
クラスの解説とか。

ちなみにこの辺の関数の仕様上はうるう秒には標準対応しているので秒は [0, 60] が有効範囲とされています。うるう秒を実装しているかどうかは別問題。


CC BY-SA 4.0
2023-11-07T01:56:28.483
96698
2023-11-07T01:56:28.483
8589
96694
answer


使用しているコンパイラ/インタプリタ/シェル他ツールなどでそれらの値を指定した時にどのようなエラーメッセージが表示されるかで決めると良いでしょう。  
それなら根拠は明白であり、仕様であると言えるのでは？

例えばこんなメッセージが表示されます。

  * C#  
`DateTime dateTime = new DateTime(2001, 13, 1);`では  
`System.ArgumentOutOfRangeException: 'Year, Month, and Day parameters describe
an un-representable DateTime.'`

  * Python  
`x = date(2001,13,1)`では  
`ValueError: month must be in 1..12`  
あるいは月が範囲内で日が0や40だと`ValueError: day is out of range for month`

おそらく`範囲内`/`範囲外`, `正常値`/`異常値`, `有効値`/`無効値`といった対比で表現されるのでは？

オーバーフロー/アンダーフローは日付時刻の変数をカウンタやインデックスとして兼用している場合に、それらの用途として取り扱った場合には言えなくもないでしょうが、微妙に違和感のある表現ですね。

* * *

あと構想されている内容では、[TimeSpan](https://learn.microsoft.com/ja-
jp/dotnet/api/system.timespan?view=net-7.0) とか
[timedelta](https://docs.python.org/ja/3/library/datetime.html#timedelta-
objects) 等の2つの時刻の差とか経過時間を計算するためのオブジェクト/クラスの仕様とかも参考になるのでは？


CC BY-SA 4.0
2023-11-07T02:55:32.643
96699
2023-11-07T03:10:34.107
2023-11-07T03:10:34.107
26370
26370
96694
answer


整数の理屈を日付には当てはめることについてはまず脇に置いて、「オーバーフロー」という用語の意味にブレがあることを説明します。

プログラミング言語 C の仕様書では整数が大きくなりすぎて一周して小さくなるような挙動 (いわゆるラップアラウンド)
が規定されている状況を「オーバーフローしない」と言い切っています。 表せる範囲外になって結果が **未定義**
になるときがオーバーフローであり、一旦は範囲を超えても結果が規定されているのはオーバーフローではないのです。

しかしこれはあくまでも C
の仕様書における用語法であって、ラップアラウンドしようがしまいが上限を超えたときをオーバーフローと呼ぶのはごく普通にあることですし、大雑把な概念はともかくとして細かな挙動の部分では分野によって違う意味を持つこともある一例と言えるでしょう。

ひとつの文書の中で **一貫した意味付けをする** のであれば近い意味合いで使われている用語を持ってくるという選択も悪いわけではありません。
ただ、その意味付けを読者が読み取れなければ意味がありませんから、ピッタリと当て嵌まるとは言えない用語を使うのであれば用語の意味を定義する項目を設置するべきですし、頻出する概念でないなら冗長でも説明的な言い回しにするのが好ましいと思います。


CC BY-SA 4.0
2023-11-07T13:23:16.483
96706
2023-11-07T13:23:16.483
3364
96694
answer