summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authormrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-26 15:54:38 +0000
committermrkn <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-07-26 15:54:38 +0000
commit1d0cef8f02ab78eddd8900899bfe39e6b6e00d97 (patch)
tree80b8b9481b7177d1deb15a2f8fe4931c27b58c1b /ext
parent798355f6e33b854a00252f680f00ebb94b7b1355 (diff)
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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@32682 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext')
-rw-r--r--ext/bigdecimal/bigdecimal.c40
1 files changed, 38 insertions, 2 deletions
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 <assert.h>
+
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
@@ -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: