From a238140726b6ce044e89b80b465a9ce0deda8757 Mon Sep 17 00:00:00 2001 From: mrkn Date: Tue, 26 Jul 2011 15:40:23 +0000 Subject: * 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32674 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/bigdecimal/bigdecimal.c | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'ext') diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c index 0997dd6ad2..b3360451a9 100644 --- a/ext/bigdecimal/bigdecimal.c +++ b/ext/bigdecimal/bigdecimal.c @@ -19,6 +19,11 @@ #endif #include "bigdecimal.h" +#ifndef BIGDECIMAL_DEBUG +# define NDEBUG +#endif +#include + #include #include #include @@ -125,6 +130,7 @@ static unsigned short VpGetException(void); 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 @@ VpCreateRbObject(size_t mx, const char *str) 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 @@ BigDecimal_power_op(VALUE self, VALUE exp) * * 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 @@ BigDecimal_new(int argc, VALUE *argv, VALUE self) } 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: -- cgit v1.2.1