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

ruby-changes:20626

From: mrkn <ko1@a...>
Date: Wed, 27 Jul 2011 00:40:33 +0900 (JST)
Subject: [ruby-changes:20626] mrkn:r32674 (trunk): * bigdecimal/bigdecimal.c (VpDup) a new function for duplicating

mrkn	2011-07-27 00:40:23 +0900 (Wed, 27 Jul 2011)

  New Revision: 32674

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

  Log:
    * bigdecimal/bigdecimal.c (VpDup) a new function for duplicating
      a BigDecimal.
    
    * bigdecimal/bigdecimal.c (BigDecimal_new): support generating a new
      BigDecimal from another BigDecimal using BigDecimal global function
      or constructor.  [ruby-dev:44245]

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 32673)
+++ ChangeLog	(revision 32674)
@@ -1,3 +1,12 @@
+Wed Jul 27 00:27:00 2011  Kenta Murata  <mrkn@m...>
+
+	* bigdecimal/bigdecimal.c (VpDup) a new function for duplicating
+	  a BigDecimal.
+
+	* bigdecimal/bigdecimal.c (BigDecimal_new): support generating a new
+	  BigDecimal from another BigDecimal using BigDecimal global function
+	  or constructor.  [ruby-dev:44245]
+
 Tue Jul 26 23:33:24 2011  Igor Zubkov  <igor.zubkov@g...>
 
 	* array.c: Fix typo. https://github.com/ruby/ruby/pull/36
Index: ext/bigdecimal/bigdecimal.c
===================================================================
--- ext/bigdecimal/bigdecimal.c	(revision 32673)
+++ ext/bigdecimal/bigdecimal.c	(revision 32674)
@@ -19,6 +19,11 @@
 #endif
 #include "bigdecimal.h"
 
+#ifndef BIGDECIMAL_DEBUG
+# define NDEBUG
+#endif
+#include <assert.h>
+
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -125,6 +130,7 @@
 static void  VpSetException(unsigned short f);
 static void  VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v);
 static int   VpLimitRound(Real *c, size_t ixDigit);
+static Real *VpDup(Real const* const x);
 
 /*
  *  **** BigDecimal part ****
@@ -530,6 +536,27 @@
     return pv;
 }
 
+static Real *
+VpDup(Real const* const x)
+{
+    Real *pv;
+
+    assert(x != NULL);
+
+    pv = VpMemAlloc(sizeof(Real) + x->MaxPrec * sizeof(BDIGIT));
+    pv->MaxPrec = x->MaxPrec;
+    pv->Prec = x->Prec;
+    pv->exponent = x->exponent;
+    pv->sign = x->sign;
+    pv->flag = x->flag;
+    MEMCPY(pv->frac, x->frac, BDIGIT, pv->MaxPrec);
+
+    pv->obj = TypedData_Wrap_Struct(
+	rb_obj_class(x->obj), &BigDecimal_data_type, pv);
+
+    return pv;
+}
+
 /* Returns True if the value is Not a Number */
 static VALUE
 BigDecimal_IsNaN(VALUE self)
@@ -2190,8 +2217,10 @@
  *
  * Create a new BigDecimal object.
  *
- * initial:: The initial value, as a String. Spaces are ignored, unrecognized
- *           characters terminate the value.
+ * initial:: The initial value, as an Integer, a Float, a Rational,
+ *           a BigDecimal, or a String.
+ *           If it is a String, spaces are ignored and unrecognized characters
+ *           terminate the value.
  *
  * digits:: The number of significant digits, as a Fixnum. If omitted or 0,
  *          the number of significant digits is determined from the initial
@@ -2217,6 +2246,13 @@
     }
 
     switch (TYPE(iniValue)) {
+      case T_DATA:
+	if (is_kind_of_BigDecimal(iniValue)) {
+	    pv = VpDup(DATA_PTR(iniValue));
+	    return ToValue(pv);
+	}
+	break;
+
       case T_FIXNUM:
 	/* fall through */
       case T_BIGNUM:
Index: test/bigdecimal/test_bigdecimal.rb
===================================================================
--- test/bigdecimal/test_bigdecimal.rb	(revision 32673)
+++ test/bigdecimal/test_bigdecimal.rb	(revision 32674)
@@ -74,6 +74,19 @@
     assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) }
   end
 
+  def test_global_new_with_big_decimal
+    assert_equal(BigDecimal(1), BigDecimal(BigDecimal(1)))
+    assert_equal(BigDecimal('+0'), BigDecimal(BigDecimal('+0')))
+    assert_equal(BigDecimal('-0'), BigDecimal(BigDecimal('-0')))
+    BigDecimal.save_exception_mode do
+      BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+      BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+      assert_positive_infinite(BigDecimal(BigDecimal('Infinity')))
+      assert_negative_infinite(BigDecimal(BigDecimal('-Infinity')))
+      assert_nan(BigDecimal(BigDecimal('NaN')))
+    end
+  end
+
   def test_new
     assert_equal(1, BigDecimal.new("1"))
     assert_equal(1, BigDecimal.new("1", 1))
@@ -111,6 +124,19 @@
     assert_nothing_raised { BigDecimal.new(0.1, Float::DIG + 1) }
   end
 
+  def test_new_with_big_decimal
+    assert_equal(BigDecimal(1), BigDecimal.new(BigDecimal(1)))
+    assert_equal(BigDecimal('+0'), BigDecimal.new(BigDecimal('+0')))
+    assert_equal(BigDecimal('-0'), BigDecimal.new(BigDecimal('-0')))
+    BigDecimal.save_exception_mode do
+      BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
+      BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
+      assert_positive_infinite(BigDecimal.new(BigDecimal('Infinity')))
+      assert_negative_infinite(BigDecimal.new(BigDecimal('-Infinity')))
+      assert_nan(BigDecimal(BigDecimal.new('NaN')))
+    end
+  end
+
   def _test_mode(type)
     BigDecimal.mode(type, true)
     assert_raise(FloatDomainError) { yield }

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

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