ruby-changes:20635
From: mrkn <ko1@a...>
Date: Wed, 27 Jul 2011 00:54:54 +0900 (JST)
Subject: [ruby-changes:20635] mrkn:r32682 (ruby_1_9_3): Merge revision 32674:
mrkn 2011-07-27 00:54:38 +0900 (Wed, 27 Jul 2011) New Revision: 32682 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32682 Log: Merge revision 32674: * 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: branches/ruby_1_9_3/ext/bigdecimal/bigdecimal.c branches/ruby_1_9_3/test/bigdecimal/test_bigdecimal.rb Index: ruby_1_9_3/ext/bigdecimal/bigdecimal.c =================================================================== --- ruby_1_9_3/ext/bigdecimal/bigdecimal.c (revision 32681) +++ ruby_1_9_3/ext/bigdecimal/bigdecimal.c (revision 32682) @@ -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: ruby_1_9_3/test/bigdecimal/test_bigdecimal.rb =================================================================== --- ruby_1_9_3/test/bigdecimal/test_bigdecimal.rb (revision 32681) +++ ruby_1_9_3/test/bigdecimal/test_bigdecimal.rb (revision 32682) @@ -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/