[前][次][番号順一覧][スレッド一覧]

ruby-changes:25457

From: marcandre <ko1@a...>
Date: Wed, 7 Nov 2012 02:14:26 +0900 (JST)
Subject: [ruby-changes:25457] marcandRe: r37514 (trunk): * numeric.c: Extract ruby_float_step_size

marcandre	2012-11-07 02:14:16 +0900 (Wed, 07 Nov 2012)

  New Revision: 37514

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37514

  Log:
    * numeric.c: Extract ruby_float_step_size
      [Feature #6636]

  Modified files:
    trunk/numeric.c

Index: numeric.c
===================================================================
--- numeric.c	(revision 37513)
+++ numeric.c	(revision 37514)
@@ -1720,41 +1720,45 @@
     return flo_truncate(rb_Float(num));
 }
 
+static double
+ruby_float_step_size(double beg, double end, double unit, int excl) {
+    const double epsilon = DBL_EPSILON;
+    double n = (end - beg)/unit;
+    double err = (fabs(beg) + fabs(end) + fabs(end-beg)) / fabs(unit) * epsilon;
 
+    if (isinf(unit)) {
+	return unit > 0 ? beg <= end : beg >= end;
+    }
+    if (err>0.5) err=0.5;
+    if (excl) {
+	if (n<=0) return 0;
+	if (n<1)
+	    n = 0;
+	else
+	    n = floor(n - err);
+    }
+    else {
+	if (n<0) return 0;
+	n = floor(n + err);
+    }
+    return n+1;
+}
+
 int
 ruby_float_step(VALUE from, VALUE to, VALUE step, int excl)
 {
     if (RB_TYPE_P(from, T_FLOAT) || RB_TYPE_P(to, T_FLOAT) || RB_TYPE_P(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;
+	double n = ruby_float_step_size(beg, end, unit, excl);
 	long i;
 
-	if (isinf(unit)) {
-	    if (unit > 0 ? beg <= end : beg >= end) rb_yield(DBL2NUM(beg));
+	for (i=0; i<n; i++) {
+	    double d = i*unit+beg;
+	    if (unit >= 0 ? end < d : d < end) d = end;
+	    rb_yield(DBL2NUM(d));
 	}
-	else {
-	    if (err>0.5) err=0.5;
-	    if (excl) {
-		if (n<=0) return TRUE;
-		if (n<1)
-		    n = 0;
-		else
-		    n = floor(n - err);
-	    }
-	    else {
-		if (n<0) return TRUE;
-		n = floor(n + err);
-	    }
-	    for (i=0; i<=n; i++) {
-		double d = i*unit+beg;
-		if (unit >= 0 ? end < d : d < end) d = end;
-		rb_yield(DBL2NUM(d));
-	    }
-	}
 	return TRUE;
     }
     return FALSE;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]