[Bug:1.9] exact Time and inexact Time

e$B1sF#$G$9!#e(B

e$B8=:_!"e(BTime#- e$B$,e(B Rational e$B$rJV$9$h$&$K$J$C$F$$$^$9!#e(B

$ ./ruby -e ‘p Time.now - Time.now’
(-7/156250)

e$B$7$+$7!"e(BTime.now e$B$N$h$&$Ke(B inexact
e$B$J;~9o$N:9J,$,!"e(Bexact e$B$Ne(B
e$B$h$&$K8+$($ke(B Rational e$B$K$J$k$N$O$h$/$J$$$H;W$$$^$9!#e(B

Time.gm(2000) e$B$J$I$Oe(B exact e$B$J;~9o$H9M$($i$l$^$9$,!"$=$l$G$be(B
e$B0J2<$Ge(B Rational e$B$,JV$k$N$O9%$^$7$/$J$$$H;W$$$^$9!#e(B

$ ./ruby -e ‘p Time.gm(2000) + 0.1 - Time.gm(2000)’
(3602879701896397/36028797018963968)

e$B$h$C$Fe(B Time e$B%*%V%8%’%/%H$Ke(B exact
e$B$+$I$&$+$r$"$i$o$9%U%i%0$re(B
e$B;}$?$;$kI,MW$,$"$k$N$G$O$J$$$G$7$g$&$+!#e(B

e$B$?$@!"e(BTime#- e$B$,e(B Rational
e$B$rJV$7$F$b$h$$$H;W$o$l$kNc$O!"e(B

$ ./ruby -e ‘p Time.gm(2000) + Rational(1, 2) - Time.gm(2000)’
(1/2)

e$B$/$i$$$7$+;W$$$D$-$^$;$s!#$J$N$Ge(B Time#- e$B$N7k2L$r>o$Ke(B Integer
e$B$^$?$Oe(B Float e$B$K$9$k$H$$$&A*Br$b$"$k$+$b$7$l$^$;$s!#e(B

e$B$H$j$"$($:LdBjDs5/$HDs0F$G$9!#$I$&;W$o$l$^$9$G$7$g$&!#e(B

In article
[email protected],
Yusuke ENDOH [email protected] writes:

e$B8=:_!"e(BTime#- e$B$,e(B Rational e$B$rJV$9$h$&$K$J$C$F$$$^$9!#e(B

$ ./ruby -e ‘p Time.now - Time.now’
(-7/156250)

e$B$7$+$7!"e(BTime.now e$B$N$h$&$Ke(B inexact e$B$J;~9o$N:9J,$,!"e(Bexact e$B$Ne(B
e$B$h$&$K8+$($ke(B Rational e$B$K$J$k$N$O$h$/$J$$$H;W$$$^$9!#e(B

e$B0lHL$K?tCM7W;;$G$O!“CM$,;}$D8m:9$h$j$b=<J,$K9b$$@:EY$r;}$C$Fe(B
e$B$$$k?tCMI=8=$r;H$&I,MW$,$”$k$s$8$c$J$$$G$7$g$&$+!#e(B

e$B$?$H$($P!"Hf3SEC;$$;~4V$r07$&MQES$G$O!"e(Bdouble e$B$OBEEv$JABre(B
e$B;h$+$b$7$l$^$;$s!#e(B

e$B$7$+$7!“0[$J$ke(B Epoch e$B$XJQ49$9$k$H$$$&MQES$G$Oe(B double
e$B$G$O=<e(B
e$BJ,$G$J$$$3$H$b$”$k$G$7$g$&!#e(B

e$B$I$A$i$be(B Time e$BF1;N$N0z$-;;$G<B8=$G$-$^$9$,!"I,MW$J@:EY$O0[$Je(B
e$B$j$^$9!#e(B

e$B$A$J$_$K!“e(BUnix Epoch e$B$+$i%J%NICC10L$G?t$($k$H!”:#$N;~9o$Oe(B
double e$B$G2<$N$[$&$N%S%C%H$rI=8=$G$-$^$;$s!#$J$N$G!“e(Bdouble e$B7Pe(B
e$BM3$GB>$Ne(B Epoch e$B$KJQ49$7$F!“JQ49$7$?B&$G7W;;$9$k$H!”@:EY$,Mne(B
e$B$A$F$$$FE,@Z$JCM$K$J$i$J$$!”$H$$$&2DG=@-$b$"$j$^$9!#$^$!!"6qe(B
e$BBNE*$Je(B Epoch e$B$HJQ49$N$d$j$+$?$K$b$h$j$^$9$,!#e(B

inexact, exact e$B$H$$$&C1=c$J6hJL$G$O$J$/$F!“MQK!$K$h$C$F$I$Ne(B
e$B$/$i$$$N8m:9$,5vMF$G$-$k$+!”$H$$$&E@$r5DO@$9$kI,MW$,$"$k$N$Ge(B
e$B$O$J$$$G$7$g$&$+!#e(B

卜部です。

Tanaka A. さんは書きました:

一般に数値計算では、値が持つ誤差よりも充分に高い精度を持って
いる数値表現を使う必要があるんじゃないでしょうか。

無闇矢鱈に高けりゃいいってもんでもないはずです。

たとえばRationalは無限に高い精度を持つものと考えるのが一般的であると思います。
すると、もしTime.nowが誤差を含んでいるのだとしたら、それをRationalで表現すると
ã€Œèª¤å·®ã‚’å«ã‚“ã§ã„ã‚‹ã€ã¨ã„ã†æƒ…å ±ã‚’å¤±ã„ã¾ã™ã®ã§ã€Rationalは不適切です。

どのぐらいの誤差を許容できるかが用法によって異なるのに本気で取り組む気があるな
ã‚‰ã€ãã¡ã‚“ã¨èª¤å·®ã‚’æ‰±ãˆã‚‹ãƒ‡ãƒ¼ã‚¿æ§‹é€ ã€ãŸã¨ãˆã°BigDecimalなどを採用すべきだと思い
ます。

e$B1sF#$G$9!#e(B

2009/05/15 0:00 Tanaka A. [email protected]:

e$B0lHL$K?tCM7W;;$G$O!“CM$,;}$D8m:9$h$j$b=<J,$K9b$$@:EY$r;}$C$Fe(B
e$B$$$k?tCMI=8=$r;H$&I,MW$,$”$k$s$8$c$J$$$G$7$g$&$+!#e(B

e$B?tCM7W;;$NLdBj$b$“$k$+$b$7$l$^$;$s$,!”;d$O%$%s%?!<%U%'%$%9$Ne(B
e$BLdBj$r5$$K$7$F$$$^$9!#e(B

e$BKNIt$5$s$b$*$C$7$c$C$F$$$^$9$,!“e(BRational
e$B$O!V8m:9$,$J$$?tCM!W$re(B
e$BI=8=$7$F$$$k$h$&$K$7$+8+$($:!”!V==J,$K9b$$@:EY$r;}$C$F$$$k?tCM!We(B
e$B$H$7$F;H$o$l$F$$$k$H$O9M$(IU$-$^$;$s!#e(B

e$B$=$N$?$a!“:GDc$G$be(B Float e$B$+$ie(B Rational
e$B$K0EL[$KJQ49$5$l$k$3$H$,e(B
e$B$”$k$N$O!"2?$i$+$N=hCV$r$9$Y$-LdBj$@$H;W$$$^$9!#6qBNE*$JJ}K!$Oe(B
e$B$H$b$+$/!#e(B

e$B$7$+$7!“0[$J$ke(B Epoch e$B$XJQ49$9$k$H$$$&MQES$G$Oe(B double e$B$G$O=<e(B
e$BJ,$G$J$$$3$H$b$”$k$G$7$g$&!#e(B

e$B$I$A$i$be(B Time e$BF1;N$N0z$-;;$G<B8=$G$-$^$9$,!"I,MW$J@:EY$O0[$Je(B
e$B$j$^$9!#e(B

e$B$$$m$$$m9M$($?$s$G$9$,!"e(BTime#to_r e$B$rMQ0U$7$?$i$I$&$G$7$g$&!#e(B
e$B8m:9$J$/e(B Epoch e$BJQ49$7$?$$?M$O!"e(Bto_r e$B$7$F@53N$Je(B Unix
Epoch e$B$Ke(B
e$B$7$F$+$i!"e(BTime e$B$G$J$/e(B Rational
e$B$G$d$C$F$/$l$H$$$&$3$H$G!#e(B

In article [email protected],
Yusuke ENDOH [email protected] writes:

e$B$$$m$$$m9M$($?$s$G$9$,!"e(BTime#to_r e$B$rMQ0U$7$?$i$I$&$G$7$g$&!#e(B
e$B8m:9$J$/e(B Epoch e$BJQ49$7$?$$?M$O!"e(Bto_r e$B$7$F@53N$Je(B Unix Epoch e$B$Ke(B
e$B$7$F$+$i!"e(BTime e$B$G$J$/e(B Rational e$B$G$d$C$F$/$l$H$$$&$3$H$G!#e(B

Time#to_r e$B$r2C$($k$N$O$"$jF@$k$H;W$$$^$9!#e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:38484] Re: [Bug:1.9] exact Time and inexact
Time”
on Sun, 17 May 2009 21:46:01 +0900, Tanaka A. [email protected]
writes:

|Time#to_r e$B$r2C$($k$N$O$"$jF@$k$H;W$$$^$9!#e(B

e$B;d$b$3$A$i$K;?@.$7$^$9!#e(B

e$B1sF#$G$9!#e(B

2009/05/18 9:05 Yukihiro M. [email protected]:

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:38484] Re: [Bug:1.9] exact Time and inexact Time”
on Sun, 17 May 2009 21:46:01 +0900, Tanaka A. [email protected] writes:

|Time#to_r e$B$r2C$($k$N$O$"$jF@$k$H;W$$$^$9!#e(B

e$B;d$b$3$A$i$K;?@.$7$^$9!#e(B

e$B$=$l$G$O%Q%C%A$r=q$-$^$7$?!#e(B

  • Time#to_r e$B$rDI2Ce(B
  • Time#- e$B$O>o$Ke(B Float e$B$rJV$9e(B (1.9.1 e$B$HF1$85sF0e(B)

e$BFC$KH?BP$,$J$1$l$P%3%_%C%H$7$h$&$H;W$$$^$9!#e(B

Index: time.c

— time.c (revision 23485)
+++ time.c (working copy)
@@ -2277,6 +2277,30 @@

/*

  • call-seq:
    • time.to_r => Rational
      
    • Returns the value of time as a rational number of seconds
    • since the Epoch.
    • t = Time.now
      
    • p t.to_r            #=> (8807170717088293/8388608)
      
    • This method is intended to be used to get an accurate value
    • representing nanoseconds from the Epoch. You can use this
    • to convert time to another Epoch.
  • */

+static VALUE
+time_to_r(VALUE time)
+{

  • struct time_object *tobj;
  • GetTimeval(time, tobj);
  • return tobj->timev;
    +}

+/*

    • call-seq:
    • time.usec    => int
      
    • time.tv_usec => int
      

@@ -2803,7 +2827,7 @@
struct time_object *tobj2;

GetTimeval(time2, tobj2);

  •    return sub(tobj->timev, tobj2->timev);
    
  •    return rb_Float(sub(tobj->timev, tobj2->timev));
    

    }
    return time_add(tobj, time2, -1);
    }
    @@ -3682,6 +3706,7 @@

    rb_define_method(rb_cTime, “to_i”, time_to_i, 0);
    rb_define_method(rb_cTime, “to_f”, time_to_f, 0);

  • rb_define_method(rb_cTime, “to_r”, time_to_r, 0);
    rb_define_method(rb_cTime, “<=>”, time_cmp, 1);
    rb_define_method(rb_cTime, “eql?”, time_eql, 1);
    rb_define_method(rb_cTime, “hash”, time_hash, 0);

e$B%A%1%C%He(B #1481 e$B$,99?7$5$l$^$7$?!#e(B (by Yukihiro M.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
ruby -v 1.9.1e$B$K%;%C%He(B

redundant

http://redmine.ruby-lang.org/issues/show/1481

e$B%A%1%C%He(B #1468 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

Applied in changeset r23490.

http://redmine.ruby-lang.org/issues/show/1468