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

ruby-changes:42527

From: mrkn <ko1@a...>
Date: Fri, 15 Apr 2016 21:36:28 +0900 (JST)
Subject: [ruby-changes:42527] mrkn:r54601 (trunk): array.c: sum for Rational and Float mixed arrays

mrkn	2016-04-15 22:33:05 +0900 (Fri, 15 Apr 2016)

  New Revision: 54601

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54601

  Log:
    array.c: sum for Rational and Float mixed arrays
    
    * array.c (rb_ary_sum): apply the precision compensated algorithm
      for an array in which Rational and Float values are mixed.
    
    * test/ruby/test_array.rb (test_sum): add assertions for the above
      change.

  Modified files:
    trunk/ChangeLog
    trunk/array.c
    trunk/test/ruby/test_array.rb
Index: array.c
===================================================================
--- array.c	(revision 54600)
+++ array.c	(revision 54601)
@@ -5722,6 +5722,8 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5722
     if (RB_FLOAT_TYPE_P(e)) {
         /* Kahan's compensated summation algorithm */
         double f, c;
+
+      float_value:
         f = NUM2DBL(v);
         c = 0.0;
         for (; i < RARRAY_LEN(ary); i++) {
@@ -5735,6 +5737,8 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5737
                 x = FIX2LONG(e);
             else if (RB_TYPE_P(e, T_BIGNUM))
                 x = rb_big2dbl(e);
+            else if (RB_TYPE_P(e, T_RATIONAL))
+                x = rb_num2dbl(e);
             else
                 goto not_float;
 
@@ -5749,6 +5753,20 @@ rb_ary_sum(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/array.c#L5753
         v = DBL2NUM(f);
     }
 
+    if (RB_TYPE_P(e, T_RATIONAL)) {
+        for (; i < RARRAY_LEN(ary); i++) {
+            e = RARRAY_AREF(ary, i);
+            if (block_given)
+                e = rb_yield(e);
+            if (RB_FLOAT_TYPE_P(e)) {
+                v = rb_to_float(v);
+                goto float_value;
+            }
+            v = rb_funcall(v, idPLUS, 1, e);
+        }
+        return v;
+    }
+
     for (; i < RARRAY_LEN(ary); i++) {
         e = RARRAY_AREF(ary, i);
         if (block_given)
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 54600)
+++ ChangeLog	(revision 54601)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Apr 15 22:31:00 2016  Kenta Murata  <mrkn@m...>
+
+	* array.c (rb_ary_sum): apply the precision compensated algorithm
+	  for an array in which Rational and Float values are mixed.
+
+	* test/ruby/test_array.rb (test_sum): add assertions for the above
+	  change.
+
 Fri Apr 15 22:30:01 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* thread.c (rb_thread_setname): defer setting native thread name
Index: test/ruby/test_array.rb
===================================================================
--- test/ruby/test_array.rb	(revision 54600)
+++ test/ruby/test_array.rb	(revision 54601)
@@ -2774,6 +2774,8 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L2774
       small_number /= 10
     end
     assert_float_equal(large_number+(small_number*10), [large_number, *[small_number]*10].sum)
+    assert_float_equal(large_number+(small_number*10), [large_number/1r, *[small_number]*10].sum)
+    assert_float_equal(large_number+(small_number*11), [small_number, large_number/1r, *[small_number]*10].sum)
   end
 
   private

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

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