# 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

|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