• 締切済み

difftime()について

difftime()は、秒数の差を返すものなのに、なんでdouble型を返す仕様になっているのでしょうか? double difftime(time_t time1, time_t time0); 関数 difftime() は時刻 time0 から時刻 time1 までの経過時間を double 型で返す。 2 つの時刻の値はカレンダー時間で指定する。カレンダー時間とは紀元 (協定世界時 (UTC) 1970年1月1日 00:00:00) からの経過秒数である。 http://www.linux.or.jp/JM/html/LDP_man-pages/man3/difftime.3.html

みんなの回答

回答No.2

「1970年1月1日00:00:00からの経過秒数」ですので「1970年1月1日00:00:00と、2038年1月19日03:14:08の秒数の差」が「秒数が符号付き32ビット整数を越える」と言う可能性があります。 difftimeの仕様が決まった当時「整数は、符号付きで32ビットまで」だったので、もし、符号付き整数で答えを返してしまうと「-2147483648~2147483647秒の差」しか返せません(秒数の差なので、マイナスを返す必要がある事に注意) これでは「1970年1月1日00:00:00と、2038年1月19日03:14:08の秒数の差」や「2038年1月19日03:14:08と、1970年1月1日00:00:00」を返せません。 当時の「符号付き64ビット整数」が存在しなかった世界で「-2147483648より小さい値」や「2147483647より大きい値」を「数値で返す」には「doubleを使うしかなかった」のです。 なお、古いUnixでは、time_tは「伝統的に符号つき32ビット整数」なので「difftimeに時刻を渡す前にオーバーフローしているので無意味」です。これは「2038年問題」と言われます。 http://ja.wikipedia.org/wiki/2038%E5%B9%B4%E5%95%8F%E9%A1%8C 現在のUnix系OSでは、time_tは「2038年1月19日03:14:08以降も正しく表現出来る」ので、difftimeは「-2147483648より小さい値」や「2147483647より大きい値」を返します。 符号付き64ビット整数を使っても良かったのですが「符号付き64ビット整数は標準Cの仕様に無い」ので「標準仕様にする為に、使用できなかった」のです。

template_i
質問者

補足

くわしい解説をいただきまして、ありがとうございます。 私が勉強した範囲内では、標準Cライブラリは、ANSI/C(1989年)において仕様になったと思うのですが、私が疑問に思ったことは、何でそのときに一緒に検討しておきながら、ANSI/C標準化委員会は、time関数とdifftime関数の返り値の型にあえて違いを設定したのかということです。 time_t time(time_t* tp); double difftime(time_t time1, time_t time0); #2さんと#1さんのご回答を読んで、自分なりに考えてみました。 (1)time_t型は、特定の型に限定せずに、汎用性を持てる形にしておきたい (2)time関数の返り値をtime_t型に設定することについては、time関数の返り値を使用するgmtime等の関数を用意しておけば、time関数を使う上での不都合は特にない (3)difftime関数の返り値をtime_t型に設定すると、time_t型が整数型でない場合には、difftime関数の返り値をさらに処理する関数が必要になってくるので、difftime関数本来の目的がうしなわれてしまう。むしろdifftime関数については、返り値の型をdouble型にしておけば、2038年問題も回避でき、ミリ秒以下の返り値を持つ実装も可能性が残るから都合がよいだろう。 こんな理解で正しいでしょうか?

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

> difftime()は、秒数の差を返すものなのに、なんでdouble型を返す仕様になっているのでしょうか? 浮動小数点型でなければ、1秒以下を表現することができません。 また、汎整数型で表現可能な範囲は±2147483647秒しか表現できませんので、狭い範囲の時間しか表現できません。 > 関数 difftime() は時刻 time0 から時刻 time1 までの経過時間を double 型で返す。 > 2 つの時刻の値はカレンダー時間で指定する。カレンダー時間とは紀元 (協定世界時 (UTC) 1970年1月1日 00:00:00) からの経過秒数である。 それはLinux特有の事情です。 time_t型は暦時間を表現するための算術型ですので、long doubleでも_Boolでも、極端な話、複素数型でも構わないのです。また、分解能も秒とはかぎりません。

関連するQ&A