mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
710dc1afc0
commit
a238140726
3 changed files with 73 additions and 2 deletions
|
@ -1,3 +1,12 @@
|
|||
Wed Jul 27 00:27:00 2011 Kenta Murata <mrkn@mrkn.jp>
|
||||
|
||||
* 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@gmail.com>
|
||||
|
||||
* array.c: Fix typo. https://github.com/ruby/ruby/pull/36
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -74,6 +74,19 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
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 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
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 }
|
||||
|
|
Loading…
Reference in a new issue