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

ruby-changes:21762

From: naruse <ko1@a...>
Date: Tue, 22 Nov 2011 10:47:50 +0900 (JST)
Subject: [ruby-changes:21762] naruse:r33811 (trunk): * numeric.c (ruby_float_step): improve floating point calculations.

naruse	2011-11-22 10:47:35 +0900 (Tue, 22 Nov 2011)

  New Revision: 33811

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

  Log:
    * numeric.c (ruby_float_step): improve floating point calculations.
      [ruby-core:35753] [Bug #4576]
    
    * numeric.c (ruby_float_step): correct the error of floating point
      numbers on the excluding case.
      patched by Masahiro Tanaka [ruby-core:39608]
    
    * numeric.c (ruby_float_step): use the end value when the current
      value is greater than or equal to the end value.
      patched by Akira Tanaka [ruby-core:39612]

  Modified files:
    trunk/ChangeLog
    trunk/numeric.c
    trunk/test/ruby/test_float.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33810)
+++ ChangeLog	(revision 33811)
@@ -1,3 +1,16 @@
+Tue Nov 22 10:46:57 2011  NARUSE, Yui  <naruse@r...>
+
+	* numeric.c (ruby_float_step): improve floating point calculations.
+	  [ruby-core:35753] [Bug #4576]
+
+	* numeric.c (ruby_float_step): correct the error of floating point
+	  numbers on the excluding case.
+	  patched by Masahiro Tanaka [ruby-core:39608]
+
+	* numeric.c (ruby_float_step): use the end value when the current
+	  value is greater than or equal to the end value.
+	  patched by Akira Tanaka [ruby-core:39612]
+
 Tue Nov 22 06:59:21 2011  Tanaka Akira  <akr@f...>
 
 	* test/ruby/test_io.rb (test_fcntl_dupfd): there is no known platform
Index: numeric.c
===================================================================
--- numeric.c	(revision 33810)
+++ numeric.c	(revision 33811)
@@ -1690,11 +1690,22 @@
 	}
 	else {
 	    if (err>0.5) err=0.5;
-	    n = floor(n + err);
-	    if (!excl || ((long)n)*unit+beg < end) n++;
-	    for (i=0; i<n; i++) {
-		rb_yield(DBL2NUM(i*unit+beg));
+	    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 (end < d) d = end;
+		rb_yield(DBL2NUM(d));
+	    }
 	}
 	return TRUE;
     }
Index: test/ruby/test_float.rb
===================================================================
--- test/ruby/test_float.rb	(revision 33810)
+++ test/ruby/test_float.rb	(revision 33811)
@@ -508,4 +508,33 @@
       sleep(0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1+0.1)
     end
   end
+
+  def test_step
+    1000.times do
+      a = rand
+      b = a+rand*1000
+      s = (b - a) / 10
+      assert_equal(11, (a..b).step(s).to_a.length)
+    end
+
+    (1.0..12.7).step(1.3).each do |n|
+      assert_operator(n, :<=, 12.7)
+    end
+  end
+
+  def test_step_excl
+    1000.times do
+      a = rand
+      b = a+rand*1000
+      s = (b - a) / 10
+      assert_equal(10, (a...b).step(s).to_a.length)
+    end
+
+    assert_equal([1.0, 2.9, 4.8, 6.699999999999999], (1.0...6.8).step(1.9).to_a)
+
+    e = 1+1E-12
+    (1.0 ... e).step(1E-16) do |n|
+      assert_operator(n, :<=, e)
+    end
+  end
 end

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

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