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

ruby-changes:19824

From: mrkn <ko1@a...>
Date: Wed, 1 Jun 2011 00:33:51 +0900 (JST)
Subject: [ruby-changes:19824] mrkn:r31870 (trunk): * ext/bigdecimal/bigdecimal.c (GetVpValueWithPrec): support instantiation from

mrkn	2011-06-01 00:33:42 +0900 (Wed, 01 Jun 2011)

  New Revision: 31870

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

  Log:
    * ext/bigdecimal/bigdecimal.c (GetVpValueWithPrec): support instantiation from
      a Float through Rational.
    * ext/bigdecimal/bigdecimal.c (BigDecimal_new): ditto.
    * test/bigdecimal/test_bigdecimal.rb (test_global_new_float): add a test for
      the above changes.
    * test/bigdecimal/test_bigdecimal.rb (test_new_with_float): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/ext/bigdecimal/bigdecimal.c
    trunk/test/bigdecimal/test_bigdecimal.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 31869)
+++ ChangeLog	(revision 31870)
@@ -1,3 +1,15 @@
+Tue Jun  1 00:32:00 2011  Kenta Murata  <mrkn@m...>
+
+	* ext/bigdecimal/bigdecimal.c (GetVpValueWithPrec): support instantiation from
+	  a Float through Rational.
+
+	* ext/bigdecimal/bigdecimal.c (BigDecimal_new): ditto.
+
+	* test/bigdecimal/test_bigdecimal.rb (test_global_new_float): add a test for
+	  the above changes.
+
+	* test/bigdecimal/test_bigdecimal.rb (test_new_with_float): ditto.
+
 Tue Jun  1 00:07:00 2011  Kenta Murata  <mrkn@m...>
 
 	* ext/bigdecimal/bigdecimal.c (BigDecimal_coerce): support coerce with a
Index: ext/bigdecimal/bigdecimal.c
===================================================================
--- ext/bigdecimal/bigdecimal.c	(revision 31869)
+++ ext/bigdecimal/bigdecimal.c	(revision 31870)
@@ -50,6 +50,7 @@
 static ID id_ceiling;
 static ID id_ceil;
 static ID id_floor;
+static ID id_to_r;
 
 /* MACRO's to guard objects from GC by keeping them in stack */
 #define ENTER(n) volatile VALUE vStack[n];int iStack=0
@@ -145,6 +146,11 @@
 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);
+	/* fall through */
       case T_RATIONAL:
 	if (prec < 0) goto unable_to_coerce_without_prec;
 
@@ -171,6 +177,7 @@
 	    goto SomeOneMayDoIt;
 	}
 	break;
+
       case T_FIXNUM:
 	sprintf(szD, "%ld", FIX2LONG(v));
 	return VpCreateRbObject(VpBaseFig() * 2 + 1, szD);
@@ -1803,6 +1810,11 @@
       case T_BIGNUM:
 	return ToValue(GetVpValue(iniValue, 1));
 
+      case T_FLOAT:
+	if (mf > DBL_DIG+1) {
+	    rb_raise(rb_eArgError, "precision too large.");
+	}
+	/* fall through */
       case T_RATIONAL:
 	if (NIL_P(nFig)) {
 	    rb_raise(rb_eArgError, "can't omit precision for a Rational.");
@@ -2232,6 +2244,7 @@
     id_ceiling = rb_intern_const("ceiling");
     id_ceil = rb_intern_const("ceil");
     id_floor = rb_intern_const("floor");
+    id_to_r = rb_intern_const("to_r");
 }
 
 /*
Index: test/bigdecimal/test_bigdecimal.rb
===================================================================
--- test/bigdecimal/test_bigdecimal.rb	(revision 31869)
+++ test/bigdecimal/test_bigdecimal.rb	(revision 31870)
@@ -42,6 +42,14 @@
     assert_raise(ArgumentError) { BigDecimal(1.quo(3)) }
   end
 
+  def test_global_new_with_float
+    assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4))
+    assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4))
+    assert_raise(ArgumentError) { BigDecimal(0.1) }
+    assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) }
+    assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) }
+  end
+
   def test_new
     assert_equal(1, BigDecimal.new("1"))
     assert_equal(1, BigDecimal.new("1", 1))
@@ -70,6 +78,14 @@
     assert_raise(ArgumentError) { BigDecimal.new(1.quo(3)) }
   end
 
+  def test_new_with_float
+    assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4))
+    assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4))
+    assert_raise(ArgumentError) { BigDecimal.new(0.1) }
+    assert_raise(ArgumentError) { BigDecimal.new(0.1, Float::DIG + 2) }
+    assert_nothing_raised { BigDecimal.new(0.1, Float::DIG + 1) }
+  end
+
   def _test_mode(type)
     BigDecimal.mode(type, true)
     assert_raise(FloatDomainError) { yield }

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

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