Project

General

Profile

Bug #2733

rubyspec: Time#+ rounds micro seconds rather than truncates FAILED

Added by mame (Yusuke Endoh) almost 10 years ago. Updated over 8 years ago.

Status:
Rejected
Priority:
Normal
Target version:
ruby -v:
ruby 1.9.1p243 (2009-07-16 revision 24175) [x86_64-linux]
Backport:
[ruby-dev:40384]

Description

=begin
akr さん
遠藤です。

Evan Phoenix と Time の挙動について相談した上で Time について一応の
確認です。

  • 1.8 の Time#+ は usec で四捨五入していますが、1.9 ではしません。
    内部表現が Rational になったのだから当然だと思いますが、仕様変更
    ですよね。

  • 1.8 の Time#usec や nsec が四捨五入しないのは仕様ですよね。
    usec が 1000000 とかになったら嫌ですものね。

そうだよんと言ってくだされば、以下のコミットを rubyspec にコミット
しようと思います。

diff --git a/core/time/plus_spec.rb b/core/time/plus_spec.rb
index 1f5c85f..e333430 100644
--- a/core/time/plus_spec.rb
+++ b/core/time/plus_spec.rb
@@ -10,21 +10,33 @@ describe "Time#+" do
(Time.at(1.1) + 0.9).should == Time.at(0.9) + 1.1
end

  • it "rounds micro seconds rather than truncates" do
  • # The use of 8.9999999 is intentional. This is because
  • # Time treats the fractional part as the number of micro seconds.
  • # Thusly it multiplies the result by 1_000_000 to go from
  • # seconds to microseconds. That conversion should be rounded
  • # properly. In this case, it's rounded up to 1,000,000, and thus
  • # contributes a full extra second to the Time object.
  • t = Time.at(0) + 8.9999999
  • t.should == Time.at(9)
  • t.usec.should == 0
  • ruby_version_is "" ... "1.9" do
  • it "rounds micro seconds rather than truncates" do
  • # The use of 8.9999999 is intentional. This is because
  • # Time treats the fractional part as the number of micro seconds.
  • # Thusly it multiplies the result by 1_000_000 to go from
  • # seconds to microseconds. That conversion should be rounded
  • # properly. In this case, it's rounded up to 1,000,000, and thus
  • # contributes a full extra second to the Time object.
  • t = Time.at(0) + 8.9999999
  • t.should == Time.at(9)
  • t.usec.should == 0 +
  • # Check the non-edge case works properly, that the fractional part
  • # contributes to #usecs
  • t2 = Time.at(0) + 8.9
  • t2.usec.should == 900000
  • end
  • end

  • # Check the non-edge case works properly, that the fractional part

  • # contributes to #usecs

  • t2 = Time.at(0) + 8.9

  • t2.usec.should == 900000

  • ruby_version_is "1.9" do

  • it "does NOT round" do

  •  t = Time.at(0) + Rational(8_999_999_999_999_999, 1_000_000_000_000_000)
    
  •  t.should_not == Time.at(9)
    
  •  t.usec.should == 999_999
    
  •  t.nsec.should == 999_999_999
    
  •  t.subsec.should == Rational(999_999_999_999_999, 1_000_000_000_000_000)
    
  • end
    end

    ruby_version_is "" ... "1.9" do

--
Yusuke ENDOH mame@tsg.ne.jp
=end

History

#1

Updated by mame (Yusuke Endoh) almost 10 years ago

=begin
遠藤です。

2010年2月11日21:36 Tanaka Akira akr@fsij.org:

2010年2月11日2:58 Yusuke ENDOH mame@tsg.ne.jp:

  • 1.8 の Time#+ は usec で四捨五入していますが、1.9 ではしません。 内部表現が Rational になったのだから当然だと思いますが、仕様変更 ですよね。

1.9.2 ではそうです。
1.9.1 の内部表現は nsec 単位なので、nsec で四捨五入なんではないかと思います。

  • 1.8 の Time#usec や nsec が四捨五入しないのは仕様ですよね。 usec が 1000000 とかになったら嫌ですものね。

1.8 に nsec はありませんが、まぁそうならざるを得ないですかね。

ありがとうございます。コミットさせて頂きました。

ちなみに rubyspec は 1.9.1 の仕様を無視する方針らしいです (1.9.1 と
1.9.2 の間で仕様変更がありすぎだから) 。なので、1.9 と書いてあれば
1.9.2 以降を指すということです。

繰り上がる先がある場合はどうかなぁ。

個人的には切り捨てがわかりやすいのでそれでいいと思いますが、変える
なら変えてもらっても構わないです。rubyspec 側を修正します。

--
Yusuke ENDOH mame@tsg.ne.jp

=end

#2

Updated by kosaki (Motohiro KOSAKI) almost 10 years ago

=begin

個人的には切り捨てがわかりやすいのでそれでいいと思いますが、変える
なら変えてもらっても構わないです。rubyspec 側を修正します。

仕掛けがわかりやすいからといって結果がわかりやすいかというと
微妙なのではないかと。

切り捨てで処理するのは崖っぷちを歩くようなもので、
ひとつ間違えると意図せざる結果になりがちです。

とりあえず Time#round(ndigits) とかどうかなぁ。

Timeの元データは何があるんでしょう?一番苦情がくるのは oldtime > newtime または oldtime > now
になってしまうケースで、oldtimeが精度落とすときに切り上げされていてnowが高精度だったりすると
起こせそうな気がします。

個人的には切り捨てに一票で、理由は「え、思ってたよりちょっと古い時刻だった?そりゃ測定してるうちにも時間は
経過するからねHAHAHA」でほとんどのケースは済んでしまうコーナーケースの少なさに利点があるかと。

=end

#3

Updated by naruse (Yui NARUSE) almost 10 years ago

  • Category set to core
  • Status changed from Open to Assigned
  • Assignee set to akr (Akira Tanaka)
  • Target version set to 1.9.2
  • ruby -v set to ruby 1.9.1p243 (2009-07-16 revision 24175) [x86_64-linux]

=begin

=end

#4

Updated by mame (Yusuke Endoh) almost 10 years ago

  • Status changed from Assigned to Rejected

=begin
遠藤です。

解決済みなので close します。

--
Yusuke Endoh mame@tsg.ne.jp
=end

Also available in: Atom PDF