Numeric#step

e$B$U$J$P$G$9!#e(B

Numeric#step e$B$G$9$,!“e(B1.0/0 = e$BL58BBg$G$”$k$H$-!"e(B

$ ruby -v -eInf=1.0/0 -e’1.step(Inf, Inf){|x| p x}’
ruby 1.8.4 (2005-12-24) [i386-freebsd5.4]

$ ruby -v -r bigdecimal -r bigdecimal/util -eInf=1.0/0
-e"‘1’.to_d.step(Inf, Inf){|x| p x}"
ruby 1.8.4 (2005-12-24) [i386-freebsd5.4]

e$B>e$N$U$?$D$N>l9g$O!"D>$A$K=*N;$7$^$9$,!"e(B

$ ruby -v -r bigdecimal -r bigdecimal/util -eInf=1.0/0
-e"‘1’.to_d.step(Inf.to_d, Inf.to_d){|x| p x}"

e$B$3$N>l9g$O=*N;$9$kMM;R$,$"$j$^$;$s!#7k2L$,$^$k$G0c$$$^$9$,!"K>$^$7$$?6e(B
e$BIq$$$H$O$I$&$$$&$b$N$G$7$g$&$+!#e(B

e$B$^$?!"e(B

$ ruby -v -eInf=1.0/0 -e’10.step(1, Inf){|x| p x}’
ruby 1.8.4 (2005-12-24) [i386-freebsd5.4]
NaN

e$B>e$N$h$&$J>l9g$O!"e(BNaN e$B$r0lEY0u;z$7$^$9$,!"e(B

$ ruby -v -r bigdecimal -r bigdecimal/util -eInf=1.0/0
-e"‘10’.to_d.step(1, Inf.to_d){|x| p x}"
ruby 1.8.4 (2005-12-24) [i386-freebsd5.4]

e$B$3$A$i$OD>$A$K=*N;$7$^$9!#e(B

|From: Tadayoshi F. [email protected]
|Date: Mon, 17 Jul 2006 21:44:58 +0900

Numeric#step e$B$G$9$,!“e(B1.0/0 = e$BL58BBg$G$”$k$H$-!"e(B

$ ruby -v -eInf=1.0/0 -e’1.step(Inf, Inf){|x| p x}’
ruby 1.8.4 (2005-12-24) [i386-freebsd5.4]

$ ruby -v -eInf=1.0/0 -e’10.step(1, Inf){|x| p x}’
ruby 1.8.4 (2005-12-24) [i386-freebsd5.4]
NaN

e$BK>$^$7$$?6Iq$$$,$I$&$$$&$b$N$+$O$o$+$j$^$;$s$,!"e(B
Floate$B$N>l9g$Ke(BNaNe$B$,=P$k$N$O$^$:$=$&$J$N$G!"e(B
e$B0J2<$N$h$&$JBP=h$r9M$($^$7$?!#e(B
e$B$D$$$G$K%k!<%W%+%&%s%?$,0n$l$k>l9g$NBP=h$b$7$F$$$^$9!#e(B
e$B7Y9p$r=P$9$+$I$&$+e(B/e$B=P$7J}$O$3$l$G$h$$$+$o$+$j$^$;$s$,!#e(B

e$BEDCf>;9(e(B

— numeric.c~ 2006-05-01 12:46:46 +0900
+++ numeric.c 2006-07-18 21:05:38 +0900
@@ -1478,22 +1478,38 @@
else if (TYPE(from) == T_FLOAT || TYPE(to) == T_FLOAT || TYPE(step)
== T_FLOAT) {
const double epsilon = DBL_EPSILON;
double beg = NUM2DBL(from);
double end = NUM2DBL(to);
double unit = NUM2DBL(step);
double n = (end - beg)/unit;
double err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) *
epsilon;
long i;

  • int warn = 0;

  • if (isinf(beg) || isinf(unit)) {

  •   if ((unit>0 && (end-beg)>=0) || (unit<0 && (end-beg)<=0)) {
    
  •       unit = 0;
    
  •       n = 0;
    
  •   } else {
    
  •       n = -1;
    
  •   }
    
  •   err = 0;
    
  • }
    if (err>0.5) err=0.5;
    n = floor(n + err) + 1;

  • if (n>LONG_MAX) {

  •   n = LONG_MAX;
    
  •   warn = 1;
    
  • }
    for (i=0; i<n; i++) {
    rb_yield(rb_float_new(i*unit+beg));
    }

  • if (warn)

  •   rb_warn("iteration is reduced to LONG_MAX times");
    

    }
    else {
    VALUE i = from;
    ID cmp;

    if (RTEST(rb_funcall(step, ‘>’, 1, INT2FIX(0)))) {
    cmp = ‘>’;
    }

  • ChangeLog

    • numeric.c (num_step): cares for Infifnity cases.
      repeats at most LONG_MAX times in Float cases.
  • e$BJQ99A0F0:ne(B

$ ./ruby -v
ruby 1.8.5 (2006-07-18) [i686-linux]
$ ./ruby -e’Inf=1.0/0; 1.step(Inf,1){|x| p x; break if x.abs>5}’
1.0
2.0
3.0
4.0
5.0
6.0
$ ./ruby -e’Inf=1.0/0; 1.step(Inf,-1){|x| p x; break if x.abs>5}’
$ ./ruby -e’Inf=1.0/0; 1.step(-Inf,1){|x| p x; break if x.abs>5}’
$ ./ruby -e’Inf=1.0/0; 1.step(-Inf,-1){|x| p x; break if x.abs>5}’
1.0
0.0
-1.0
-2.0
-3.0
-4.0
-5.0
-6.0
$ ./ruby -e’Inf=1.0/0;i=0; Inf.step(1,-1){|x| p x; break if (i+=1)>5}’
Infinity
Infinity
Infinity
Infinity
Infinity
Infinity
$ ./ruby -e’Inf=1.0/0;i=0; Inf.step(1,1){|x| p x; break if (i+=1)>5}’
$ ./ruby -e’Inf=1.0/0;i=0; (-Inf).step(1,-1){|x| p x; break if
(i+=1)>5}’
$ ./ruby -e’Inf=1.0/0;i=0; (-Inf).step(1,1){|x| p x; break if (i+=1)>5}’
-Infinity
-Infinity
-Infinity
-Infinity
-Infinity
-Infinity
$ ./ruby -e’Inf=1.0/0; 1.step(10,Inf){|x| p x}’
NaN
$ ./ruby -e’Inf=1.0/0; 1.step(-10,Inf){|x| p x}’
NaN
$ ./ruby -e’Inf=1.0/0; 1.step(10,-Inf){|x| p x}’
NaN
$ ./ruby -e’Inf=1.0/0; 1.step(-10,-Inf){|x| p x}’
NaN
$ ./ruby -e’Inf=1.0/0; 1.step(1,Inf){|x| p x}’
NaN
$ ./ruby -e’Inf=1.0/0; 1.step(1,-Inf){|x| p x}’
NaN
$ ./ruby -e’Inf=1.0/0; 1.step(Inf,Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; 1.step(Inf,-Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; 1.step(-Inf,Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; 1.step(-Inf,-Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; Inf.step(Inf,Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; Inf.step(-Inf,Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; Inf.step(Inf,-Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; Inf.step(-Inf,-Inf){|x| p x}’

  • e$BJQ998eF0:ne(B

$ ./ruby -e’Inf=1.0/0; 1.step(Inf,1){|x| p x; break if x.abs>5}‘1.0
2.0
3.0
4.0
5.0
6.0
$ ./ruby -e’Inf=1.0/0; 1.step(Inf,-1){|x| p x; break if x.abs>5}’
$ ./ruby -e’Inf=1.0/0; 1.step(-Inf,1){|x| p x; break if x.abs>5}’
$ ./ruby -e’Inf=1.0/0; 1.step(-Inf,-1){|x| p x; break if x.abs>5}’
1.0
0.0
-1.0
-2.0
-3.0
-4.0
-5.0
-6.0
$ ./ruby -e’Inf=1.0/0;i=0; Inf.step(1,-1){|x| p x; break if (i+=1)>5}’
Infinity
$ ./ruby -e’Inf=1.0/0;i=0; Inf.step(1,1){|x| p x; break if (i+=1)>5}’
$ ./ruby -e’Inf=1.0/0;i=0; (-Inf).step(1,-1){|x| p x; break if
(i+=1)>5}’
$ ./ruby -e’Inf=1.0/0;i=0; (-Inf).step(1,1){|x| p x; break if (i+=1)>5}’
-Infinity
$ ./ruby -e’Inf=1.0/0; 1.step(10,Inf){|x| p x}’
1.0
$ ./ruby -e’Inf=1.0/0; 1.step(-10,Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; 1.step(10,-Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; 1.step(-10,-Inf){|x| p x}’
1.0
$ ./ruby -e’Inf=1.0/0; 1.step(1,Inf){|x| p x}’
1.0
$ ./ruby -e’Inf=1.0/0; 1.step(1,-Inf){|x| p x}’
1.0
$ ./ruby -e’Inf=1.0/0; 1.step(Inf,Inf){|x| p x}’
1.0
$ ./ruby -e’Inf=1.0/0; 1.step(Inf,-Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; 1.step(-Inf,Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; 1.step(-Inf,-Inf){|x| p x}’
1.0
$ ./ruby -e’Inf=1.0/0; Inf.step(Inf,Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; Inf.step(-Inf,Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; Inf.step(Inf,-Inf){|x| p x}’
$ ./ruby -e’Inf=1.0/0; Inf.step(-Inf,-Inf){|x| p x}’
Infinity