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

ruby-changes:31942

From: mrkn <ko1@a...>
Date: Fri, 6 Dec 2013 01:35:08 +0900 (JST)
Subject: [ruby-changes:31942] mrkn:r44021 (trunk): * ext/bigdecimal/bigdecimal.c (GetVpValueWithPrec):

mrkn	2013-12-06 01:34:59 +0900 (Fri, 06 Dec 2013)

  New Revision: 44021

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

  Log:
    * ext/bigdecimal/bigdecimal.c (GetVpValueWithPrec):
      treat 0.0 and -0.0 of floating-point numbers specially for an optimization
      and to correctly propagate its signbit to the result.
      [Bug #9214] [ruby-core:58858]
    
    * test/bigdecimal/test_bigdecimal.rb: add tests case for the above change.
    
    * test/bigdecimal/test_bigdecimal_util.rb: ditto.

  Modified files:
    trunk/ChangeLog
    trunk/ext/bigdecimal/bigdecimal.c
    trunk/test/bigdecimal/test_bigdecimal.rb
    trunk/test/bigdecimal/test_bigdecimal_util.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 44020)
+++ ChangeLog	(revision 44021)
@@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Dec  6 01:27:00 2013  Kenta Murata  <mrkn@m...>
+
+	* ext/bigdecimal/bigdecimal.c (GetVpValueWithPrec):
+	  treat 0.0 and -0.0 of floating-point numbers specially for an optimization
+	  and to correctly propagate its signbit to the result.
+	  [Bug #9214] [ruby-core:58858]
+
+	* test/bigdecimal/test_bigdecimal.rb: add tests case for the above change.
+
+	* test/bigdecimal/test_bigdecimal_util.rb: ditto.
+
 Thu Dec  5 22:18:01 2013  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/mkmf.rb (configuration): strip destdir part from prefix to get
Index: ext/bigdecimal/bigdecimal.c
===================================================================
--- ext/bigdecimal/bigdecimal.c	(revision 44020)
+++ ext/bigdecimal/bigdecimal.c	(revision 44021)
@@ -199,14 +199,23 @@ GetVpValueWithPrec(VALUE v, long prec, i https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L199
     VALUE num, bg;
     char szD[128];
     VALUE orig = Qundef;
+    double d;
 
 again:
     switch(TYPE(v)) {
       case T_FLOAT:
 	if (prec < 0) goto unable_to_coerce_without_prec;
 	if (prec > DBL_DIG+1) goto SomeOneMayDoIt;
-	v = rb_funcall(v, id_to_r, 0);
-	goto again;
+	d = RFLOAT_VALUE(v);
+	if (d != 0.0) {
+	    v = rb_funcall(v, id_to_r, 0);
+	    goto again;
+	}
+	if (1/d < 0.0) {
+	    return VpCreateRbObject(prec, "-0");
+	}
+	return VpCreateRbObject(prec, "0");
+
       case T_RATIONAL:
 	if (prec < 0) goto unable_to_coerce_without_prec;
 
Index: test/bigdecimal/test_bigdecimal.rb
===================================================================
--- test/bigdecimal/test_bigdecimal.rb	(revision 44020)
+++ test/bigdecimal/test_bigdecimal.rb	(revision 44021)
@@ -86,6 +86,9 @@ class TestBigDecimal < Test::Unit::TestC https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L86
     assert_raise(ArgumentError) { BigDecimal(0.1) }
     assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) }
     assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) }
+
+    bug9214 = '[ruby-core:58858]'
+    assert_equal(BigDecimal(-0.0, Float::DIG).sign, -1, bug9214)
   end
 
   def test_global_new_with_big_decimal
Index: test/bigdecimal/test_bigdecimal_util.rb
===================================================================
--- test/bigdecimal/test_bigdecimal_util.rb	(revision 44020)
+++ test/bigdecimal/test_bigdecimal_util.rb	(revision 44021)
@@ -18,6 +18,9 @@ class TestBigDecimalUtil < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal_util.rb#L18
     assert_in_delta(BigDecimal(0.5, Float::DIG), 0.5.to_d, delta)
     assert_in_delta(BigDecimal(355.0/113.0, Float::DIG), (355.0/113.0).to_d, delta)
     assert_equal(9.05.to_d.to_s('F'), "9.05")
+
+    bug9214 = '[ruby-core:58858]'
+    assert_equal((-0.0).to_d.sign, -1, bug9214)
   end
 
   def test_Float_to_d_with_precision
@@ -25,6 +28,9 @@ class TestBigDecimalUtil < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal_util.rb#L28
     delta = 1.0/10**(digits)
     assert_in_delta(BigDecimal(0.5, 5), 0.5.to_d(digits), delta)
     assert_in_delta(BigDecimal(355.0/113.0, 5), (355.0/113.0).to_d(digits), delta)
+
+    bug9214 = '[ruby-core:58858]'
+    assert_equal((-0.0).to_d(digits).sign, -1, bug9214)
   end
 
   def test_Rational_to_d

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

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