mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
bigdecimal: import version 1.3.0.pre
Import bigdecimal version 1.3.0.pre. The full commit log of this changes can be found at: https://github.com/ruby/bigdecimal/compare/5c43a9e...v1.3.0.pre git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57040 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2dd993072e
commit
8e1293730e
7 changed files with 501 additions and 186 deletions
|
@ -62,6 +62,7 @@ static ID id_ceil;
|
|||
static ID id_floor;
|
||||
static ID id_to_r;
|
||||
static ID id_eq;
|
||||
static ID id_half;
|
||||
|
||||
/* MACRO's to guard objects from GC by keeping them in stack */
|
||||
#define ENTER(n) volatile VALUE RB_UNUSED_VAR(vStack[n]);int iStack=0
|
||||
|
@ -126,6 +127,9 @@ rb_rational_den(VALUE rat)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define BIGDECIMAL_POSITIVE_P(bd) ((bd)->sign > 0)
|
||||
#define BIGDECIMAL_NEGATIVE_P(bd) ((bd)->sign < 0)
|
||||
|
||||
/*
|
||||
* ================== Ruby Interface part ==========================
|
||||
*/
|
||||
|
@ -240,9 +244,8 @@ again:
|
|||
if (prec > DBL_DIG+1) goto SomeOneMayDoIt;
|
||||
d = RFLOAT_VALUE(v);
|
||||
if (!isfinite(d)) {
|
||||
pv = VpCreateRbObject(prec, NULL);
|
||||
pv->sign = isnan(d) ? VP_SIGN_NaN :
|
||||
d > 0 ? VP_SIGN_POSITIVE_INFINITE : VP_SIGN_NEGATIVE_FINITE;
|
||||
pv = VpCreateRbObject(1, NULL);
|
||||
VpDtoV(pv, d);
|
||||
return pv;
|
||||
}
|
||||
if (d != 0.0) {
|
||||
|
@ -385,9 +388,9 @@ BigDecimal_hash(VALUE self)
|
|||
* Method used to provide marshalling support.
|
||||
*
|
||||
* inf = BigDecimal.new('Infinity')
|
||||
* #=> #<BigDecimal:1e16fa8,'Infinity',9(9)>
|
||||
* #=> Infinity
|
||||
* BigDecimal._load(inf._dump)
|
||||
* #=> #<BigDecimal:1df8dc8,'Infinity',9(9)>
|
||||
* #=> Infinity
|
||||
*
|
||||
* See the Marshal module.
|
||||
*/
|
||||
|
@ -440,6 +443,54 @@ BigDecimal_load(VALUE self, VALUE str)
|
|||
return ToValue(pv);
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
check_rounding_mode_option(VALUE const opts)
|
||||
{
|
||||
VALUE mode;
|
||||
char const *s;
|
||||
long l;
|
||||
|
||||
assert(RB_TYPE_P(opts, T_HASH));
|
||||
|
||||
if (NIL_P(opts))
|
||||
goto noopt;
|
||||
|
||||
mode = rb_hash_lookup2(opts, ID2SYM(id_half), Qundef);
|
||||
if (mode == Qundef)
|
||||
goto noopt;
|
||||
|
||||
if (SYMBOL_P(mode))
|
||||
mode = rb_sym2str(mode);
|
||||
else if (!RB_TYPE_P(mode, T_STRING)) {
|
||||
VALUE str_mode = rb_check_string_type(mode);
|
||||
if (NIL_P(str_mode)) goto invalid;
|
||||
mode = str_mode;
|
||||
}
|
||||
s = RSTRING_PTR(mode);
|
||||
l = RSTRING_LEN(mode);
|
||||
switch (l) {
|
||||
case 2:
|
||||
if (strncasecmp(s, "up", 2) == 0)
|
||||
return VP_ROUND_HALF_UP;
|
||||
break;
|
||||
case 4:
|
||||
if (strncasecmp(s, "even", 4) == 0)
|
||||
return VP_ROUND_HALF_EVEN;
|
||||
else if (strncasecmp(s, "down", 4) == 0)
|
||||
return VP_ROUND_HALF_DOWN;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
invalid:
|
||||
if (NIL_P(mode))
|
||||
rb_raise(rb_eArgError, "invalid rounding mode: nil");
|
||||
else
|
||||
rb_raise(rb_eArgError, "invalid rounding mode: %"PRIsVALUE, mode);
|
||||
|
||||
noopt:
|
||||
return VpGetRoundMode();
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
check_rounding_mode(VALUE const v)
|
||||
{
|
||||
|
@ -562,7 +613,7 @@ BigDecimal_mode(int argc, VALUE *argv, VALUE self)
|
|||
fo = VpSetRoundMode(sw);
|
||||
return INT2FIX(fo);
|
||||
}
|
||||
rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid");
|
||||
rb_raise(rb_eTypeError, "first argument for BigDecimal.mode invalid");
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
|
@ -682,7 +733,7 @@ static VALUE BigDecimal_split(VALUE self);
|
|||
|
||||
/* Returns the value as an Integer.
|
||||
*
|
||||
* If the BigNumber is infinity or NaN, raises FloatDomainError.
|
||||
* If the BigDecimal is infinity or NaN, raises FloatDomainError.
|
||||
*/
|
||||
static VALUE
|
||||
BigDecimal_to_i(VALUE self)
|
||||
|
@ -707,7 +758,7 @@ BigDecimal_to_i(VALUE self)
|
|||
VALUE ret;
|
||||
ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits);
|
||||
|
||||
if (VpGetSign(p) < 0) {
|
||||
if (BIGDECIMAL_NEGATIVE_P(p)) {
|
||||
numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1));
|
||||
}
|
||||
if (dpower < 0) {
|
||||
|
@ -762,17 +813,17 @@ BigDecimal_to_f(VALUE self)
|
|||
|
||||
overflow:
|
||||
VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0);
|
||||
if (p->sign >= 0)
|
||||
return rb_float_new(VpGetDoublePosInf());
|
||||
else
|
||||
if (BIGDECIMAL_NEGATIVE_P(p))
|
||||
return rb_float_new(VpGetDoubleNegInf());
|
||||
else
|
||||
return rb_float_new(VpGetDoublePosInf());
|
||||
|
||||
underflow:
|
||||
VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0);
|
||||
if (p->sign >= 0)
|
||||
return rb_float_new(0.0);
|
||||
else
|
||||
if (BIGDECIMAL_NEGATIVE_P(p))
|
||||
return rb_float_new(-0.0);
|
||||
else
|
||||
return rb_float_new(0.0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1720,11 +1771,21 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
|||
iLoc = 0;
|
||||
break;
|
||||
case 1:
|
||||
iLoc = NUM2INT(vLoc);
|
||||
if (RB_TYPE_P(vLoc, T_HASH)) {
|
||||
sw = check_rounding_mode_option(vLoc);
|
||||
}
|
||||
else {
|
||||
iLoc = NUM2INT(vLoc);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
iLoc = NUM2INT(vLoc);
|
||||
sw = check_rounding_mode(vRound);
|
||||
if (RB_TYPE_P(vRound, T_HASH)) {
|
||||
sw = check_rounding_mode_option(vRound);
|
||||
}
|
||||
else {
|
||||
sw = check_rounding_mode(vRound);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -2066,7 +2127,7 @@ BigDecimal_exponent(VALUE self)
|
|||
* values in angle brackets with a leading #:
|
||||
*
|
||||
* BigDecimal.new("1234.5678").inspect
|
||||
* #=> "#<BigDecimal:b7ea1130,'0.12345678E4',8(12)>"
|
||||
* #=> "0.12345678e4"
|
||||
*
|
||||
* The first part is the address, the second is the value as a string, and
|
||||
* the final part ss(mm) is the current number of significant digits and the
|
||||
|
@ -2077,23 +2138,16 @@ BigDecimal_inspect(VALUE self)
|
|||
{
|
||||
ENTER(5);
|
||||
Real *vp;
|
||||
volatile VALUE obj;
|
||||
volatile VALUE str;
|
||||
size_t nc;
|
||||
char *psz, *tmp;
|
||||
|
||||
GUARD_OBJ(vp, GetVpValue(self, 1));
|
||||
nc = VpNumOfChars(vp, "E");
|
||||
nc += (nc + 9) / 10;
|
||||
|
||||
obj = rb_str_new(0, nc+256);
|
||||
psz = RSTRING_PTR(obj);
|
||||
sprintf(psz, "#<BigDecimal:%"PRIxVALUE",'", self);
|
||||
tmp = psz + strlen(psz);
|
||||
VpToString(vp, tmp, 10, 0);
|
||||
tmp += strlen(tmp);
|
||||
sprintf(tmp, "',%"PRIuSIZE"(%"PRIuSIZE")>", VpPrec(vp)*VpBaseFig(), VpMaxPrec(vp)*VpBaseFig());
|
||||
rb_str_resize(obj, strlen(psz));
|
||||
return obj;
|
||||
str = rb_str_new(0, nc);
|
||||
VpToString(vp, RSTRING_PTR(str), 0, 0);
|
||||
rb_str_resize(str, strlen(RSTRING_PTR(str)));
|
||||
return str;
|
||||
}
|
||||
|
||||
static VALUE BigMath_s_exp(VALUE, VALUE, VALUE);
|
||||
|
@ -2303,7 +2357,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|||
if (is_negative(vexp)) {
|
||||
y = VpCreateRbObject(n, "#0");
|
||||
RB_GC_GUARD(y->obj);
|
||||
if (VpGetSign(x) < 0) {
|
||||
if (BIGDECIMAL_NEGATIVE_P(x)) {
|
||||
if (is_integer(vexp)) {
|
||||
if (is_even(vexp)) {
|
||||
/* (-0) ** (-even_integer) -> Infinity */
|
||||
|
@ -2342,7 +2396,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|||
|
||||
if (VpIsInf(x)) {
|
||||
if (is_negative(vexp)) {
|
||||
if (VpGetSign(x) < 0) {
|
||||
if (BIGDECIMAL_NEGATIVE_P(x)) {
|
||||
if (is_integer(vexp)) {
|
||||
if (is_even(vexp)) {
|
||||
/* (-Infinity) ** (-even_integer) -> +0 */
|
||||
|
@ -2364,7 +2418,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|||
}
|
||||
else {
|
||||
y = VpCreateRbObject(n, "0#");
|
||||
if (VpGetSign(x) < 0) {
|
||||
if (BIGDECIMAL_NEGATIVE_P(x)) {
|
||||
if (is_integer(vexp)) {
|
||||
if (is_even(vexp)) {
|
||||
VpSetPosInf(y);
|
||||
|
@ -2405,7 +2459,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|||
}
|
||||
return ToValue(y);
|
||||
}
|
||||
else if (VpGetSign(x) < 0 && is_even(vexp)) {
|
||||
else if (BIGDECIMAL_NEGATIVE_P(x) && is_even(vexp)) {
|
||||
return ToValue(VpCreateRbObject(n, "-0"));
|
||||
}
|
||||
else {
|
||||
|
@ -2423,7 +2477,7 @@ BigDecimal_power(int argc, VALUE*argv, VALUE self)
|
|||
}
|
||||
return ToValue(y);
|
||||
}
|
||||
else if (VpGetSign(x) < 0 && is_even(vexp)) {
|
||||
else if (BIGDECIMAL_NEGATIVE_P(x) && is_even(vexp)) {
|
||||
return ToValue(VpCreateRbObject(n, "-0"));
|
||||
}
|
||||
else {
|
||||
|
@ -2545,6 +2599,7 @@ BigDecimal_new(int argc, VALUE *argv)
|
|||
size_t mf;
|
||||
VALUE nFig;
|
||||
VALUE iniValue;
|
||||
double d;
|
||||
|
||||
if (rb_scan_args(argc, argv, "11", &iniValue, &nFig) == 1) {
|
||||
mf = 0;
|
||||
|
@ -2566,6 +2621,12 @@ BigDecimal_new(int argc, VALUE *argv)
|
|||
return GetVpValue(iniValue, 1);
|
||||
|
||||
case T_FLOAT:
|
||||
d = RFLOAT_VALUE(iniValue);
|
||||
if (!isfinite(d)) {
|
||||
Real *pv = VpCreateRbObject(1, NULL);
|
||||
VpDtoV(pv, d);
|
||||
return pv;
|
||||
}
|
||||
if (mf > DBL_DIG+1) {
|
||||
rb_raise(rb_eArgError, "precision too large.");
|
||||
}
|
||||
|
@ -2766,7 +2827,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
|
|||
case T_DATA:
|
||||
if (!is_kind_of_BigDecimal(x)) break;
|
||||
vx = DATA_PTR(x);
|
||||
negative = VpGetSign(vx) < 0;
|
||||
negative = BIGDECIMAL_NEGATIVE_P(vx);
|
||||
infinite = VpIsPosInf(vx) || VpIsNegInf(vx);
|
||||
nan = VpIsNaN(vx);
|
||||
break;
|
||||
|
@ -2819,7 +2880,7 @@ BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec)
|
|||
x = vx->obj;
|
||||
|
||||
n = prec + rmpd_double_figures();
|
||||
negative = VpGetSign(vx) < 0;
|
||||
negative = BIGDECIMAL_NEGATIVE_P(vx);
|
||||
if (negative) {
|
||||
VpSetSign(vx, 1);
|
||||
}
|
||||
|
@ -2905,7 +2966,7 @@ BigMath_s_log(VALUE klass, VALUE x, VALUE vprec)
|
|||
if (!is_kind_of_BigDecimal(x)) break;
|
||||
vx = DATA_PTR(x);
|
||||
zero = VpIsZero(vx);
|
||||
negative = VpGetSign(vx) < 0;
|
||||
negative = BIGDECIMAL_NEGATIVE_P(vx);
|
||||
infinite = VpIsPosInf(vx) || VpIsNegInf(vx);
|
||||
nan = VpIsNaN(vx);
|
||||
break;
|
||||
|
@ -3208,7 +3269,7 @@ Init_bigdecimal(void)
|
|||
rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW", INT2FIX(VP_EXCEPTION_OVERFLOW));
|
||||
|
||||
/*
|
||||
* 0x01: Determines what happens when a division by zero is performed.
|
||||
* 0x10: Determines what happens when a division by zero is performed.
|
||||
* See BigDecimal.mode.
|
||||
*/
|
||||
rb_define_const(rb_cBigDecimal, "EXCEPTION_ZERODIVIDE", INT2FIX(VP_EXCEPTION_ZERODIVIDE));
|
||||
|
@ -3350,6 +3411,7 @@ Init_bigdecimal(void)
|
|||
id_floor = rb_intern_const("floor");
|
||||
id_to_r = rb_intern_const("to_r");
|
||||
id_eq = rb_intern_const("==");
|
||||
id_half = rb_intern_const("half");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3377,7 +3439,14 @@ static Real *VpPt5; /* constant 0.5 */
|
|||
#define MemCmp(x,y,z) memcmp(x,y,z)
|
||||
#define StrCmp(x,y) strcmp(x,y)
|
||||
|
||||
static int VpIsDefOP(Real *c,Real *a,Real *b,int sw);
|
||||
enum op_sw {
|
||||
OP_SW_ADD = 1, /* + */
|
||||
OP_SW_SUB, /* - */
|
||||
OP_SW_MULT, /* * */
|
||||
OP_SW_DIV /* / */
|
||||
};
|
||||
|
||||
static int VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw);
|
||||
static int AddExponent(Real *a, SIGNED_VALUE n);
|
||||
static BDIGIT VpAddAbs(Real *a,Real *b,Real *c);
|
||||
static BDIGIT VpSubAbs(Real *a,Real *b,Real *c);
|
||||
|
@ -3404,7 +3473,7 @@ VpMemAlloc(size_t mb)
|
|||
return p;
|
||||
}
|
||||
|
||||
VP_EXPORT void *
|
||||
VP_EXPORT void *
|
||||
VpMemRealloc(void *ptr, size_t mb)
|
||||
{
|
||||
void *p = xrealloc(ptr, mb);
|
||||
|
@ -3664,7 +3733,7 @@ VpException(unsigned short f, const char *str,int always)
|
|||
/* Throw exception or returns 0,when resulting c is Inf or NaN */
|
||||
/* sw=1:+ 2:- 3:* 4:/ */
|
||||
static int
|
||||
VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
||||
VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw)
|
||||
{
|
||||
if (VpIsNaN(a) || VpIsNaN(b)) {
|
||||
/* at least a or b is NaN */
|
||||
|
@ -3675,7 +3744,7 @@ VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
|||
if (VpIsInf(a)) {
|
||||
if (VpIsInf(b)) {
|
||||
switch(sw) {
|
||||
case 1: /* + */
|
||||
case OP_SW_ADD: /* + */
|
||||
if (VpGetSign(a) == VpGetSign(b)) {
|
||||
VpSetInf(c, VpGetSign(a));
|
||||
goto Inf;
|
||||
|
@ -3684,7 +3753,7 @@ VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
|||
VpSetNaN(c);
|
||||
goto NaN;
|
||||
}
|
||||
case 2: /* - */
|
||||
case OP_SW_SUB: /* - */
|
||||
if (VpGetSign(a) != VpGetSign(b)) {
|
||||
VpSetInf(c, VpGetSign(a));
|
||||
goto Inf;
|
||||
|
@ -3693,12 +3762,10 @@ VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
|||
VpSetNaN(c);
|
||||
goto NaN;
|
||||
}
|
||||
break;
|
||||
case 3: /* * */
|
||||
case OP_SW_MULT: /* * */
|
||||
VpSetInf(c, VpGetSign(a)*VpGetSign(b));
|
||||
goto Inf;
|
||||
break;
|
||||
case 4: /* / */
|
||||
case OP_SW_DIV: /* / */
|
||||
VpSetNaN(c);
|
||||
goto NaN;
|
||||
}
|
||||
|
@ -3707,18 +3774,18 @@ VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
|||
}
|
||||
/* Inf op Finite */
|
||||
switch(sw) {
|
||||
case 1: /* + */
|
||||
case 2: /* - */
|
||||
case OP_SW_ADD: /* + */
|
||||
case OP_SW_SUB: /* - */
|
||||
VpSetInf(c, VpGetSign(a));
|
||||
break;
|
||||
case 3: /* * */
|
||||
case OP_SW_MULT: /* * */
|
||||
if (VpIsZero(b)) {
|
||||
VpSetNaN(c);
|
||||
goto NaN;
|
||||
}
|
||||
VpSetInf(c, VpGetSign(a)*VpGetSign(b));
|
||||
break;
|
||||
case 4: /* / */
|
||||
case OP_SW_DIV: /* / */
|
||||
VpSetInf(c, VpGetSign(a)*VpGetSign(b));
|
||||
}
|
||||
goto Inf;
|
||||
|
@ -3726,20 +3793,20 @@ VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
|||
|
||||
if (VpIsInf(b)) {
|
||||
switch(sw) {
|
||||
case 1: /* + */
|
||||
case OP_SW_ADD: /* + */
|
||||
VpSetInf(c, VpGetSign(b));
|
||||
break;
|
||||
case 2: /* - */
|
||||
case OP_SW_SUB: /* - */
|
||||
VpSetInf(c, -VpGetSign(b));
|
||||
break;
|
||||
case 3: /* * */
|
||||
case OP_SW_MULT: /* * */
|
||||
if (VpIsZero(a)) {
|
||||
VpSetNaN(c);
|
||||
goto NaN;
|
||||
}
|
||||
VpSetInf(c, VpGetSign(a)*VpGetSign(b));
|
||||
break;
|
||||
case 4: /* / */
|
||||
case OP_SW_DIV: /* / */
|
||||
VpSetZero(c, VpGetSign(a)*VpGetSign(b));
|
||||
}
|
||||
goto Inf;
|
||||
|
@ -3747,7 +3814,13 @@ VpIsDefOP(Real *c,Real *a,Real *b,int sw)
|
|||
return 1; /* Results OK */
|
||||
|
||||
Inf:
|
||||
return VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0);
|
||||
if (VpIsPosInf(c)) {
|
||||
return VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0);
|
||||
}
|
||||
else {
|
||||
return VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 0);
|
||||
}
|
||||
|
||||
NaN:
|
||||
return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0);
|
||||
}
|
||||
|
@ -3894,7 +3967,8 @@ overflow:
|
|||
VP_EXPORT Real *
|
||||
VpAlloc(size_t mx, const char *szVal)
|
||||
{
|
||||
size_t i, ni, ipn, ipf, nf, ipe, ne, nalloc;
|
||||
const char *orig_szVal = szVal;
|
||||
size_t i, ni, ipn, ipf, nf, ipe, ne, dot_seen, exp_seen, nalloc;
|
||||
char v, *psz;
|
||||
int sign=1;
|
||||
Real *vp = NULL;
|
||||
|
@ -3929,6 +4003,26 @@ VpAlloc(size_t mx, const char *szVal)
|
|||
return vp;
|
||||
}
|
||||
|
||||
/* Check on Inf & NaN */
|
||||
if (StrCmp(szVal, SZ_PINF) == 0 || StrCmp(szVal, SZ_INF) == 0 ) {
|
||||
vp = VpAllocReal(1);
|
||||
vp->MaxPrec = 1; /* set max precision */
|
||||
VpSetPosInf(vp);
|
||||
return vp;
|
||||
}
|
||||
if (StrCmp(szVal, SZ_NINF) == 0) {
|
||||
vp = VpAllocReal(1);
|
||||
vp->MaxPrec = 1; /* set max precision */
|
||||
VpSetNegInf(vp);
|
||||
return vp;
|
||||
}
|
||||
if (StrCmp(szVal, SZ_NaN) == 0) {
|
||||
vp = VpAllocReal(1);
|
||||
vp->MaxPrec = 1; /* set max precision */
|
||||
VpSetNaN(vp);
|
||||
return vp;
|
||||
}
|
||||
|
||||
/* Skip all '_' after digit: 2006-6-30 */
|
||||
ni = 0;
|
||||
buf = rb_str_tmp_new(strlen(szVal) + 1);
|
||||
|
@ -3954,26 +4048,6 @@ VpAlloc(size_t mx, const char *szVal)
|
|||
}
|
||||
szVal = psz;
|
||||
|
||||
/* Check on Inf & NaN */
|
||||
if (StrCmp(szVal, SZ_PINF) == 0 || StrCmp(szVal, SZ_INF) == 0 ) {
|
||||
vp = VpAllocReal(1);
|
||||
vp->MaxPrec = 1; /* set max precision */
|
||||
VpSetPosInf(vp);
|
||||
return vp;
|
||||
}
|
||||
if (StrCmp(szVal, SZ_NINF) == 0) {
|
||||
vp = VpAllocReal(1);
|
||||
vp->MaxPrec = 1; /* set max precision */
|
||||
VpSetNegInf(vp);
|
||||
return vp;
|
||||
}
|
||||
if (StrCmp(szVal, SZ_NaN) == 0) {
|
||||
vp = VpAllocReal(1);
|
||||
vp->MaxPrec = 1; /* set max precision */
|
||||
VpSetNaN(vp);
|
||||
return vp;
|
||||
}
|
||||
|
||||
/* check on number szVal[] */
|
||||
ipn = i = 0;
|
||||
if (szVal[i] == '-') { sign=-1; ++i; }
|
||||
|
@ -3989,9 +4063,12 @@ VpAlloc(size_t mx, const char *szVal)
|
|||
ipf = 0;
|
||||
ipe = 0;
|
||||
ne = 0;
|
||||
dot_seen = 0;
|
||||
exp_seen = 0;
|
||||
if (v) {
|
||||
/* other than digit nor \0 */
|
||||
if (szVal[i] == '.') { /* xxx. */
|
||||
dot_seen = 1;
|
||||
++i;
|
||||
ipf = i;
|
||||
while ((v = szVal[i]) != 0) { /* get fraction part. */
|
||||
|
@ -4007,6 +4084,7 @@ VpAlloc(size_t mx, const char *szVal)
|
|||
break;
|
||||
case 'e': case 'E':
|
||||
case 'd': case 'D':
|
||||
exp_seen = 1;
|
||||
++i;
|
||||
ipe = i;
|
||||
v = szVal[i];
|
||||
|
@ -4021,6 +4099,11 @@ VpAlloc(size_t mx, const char *szVal)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (((ni == 0 || dot_seen) && nf == 0) || (exp_seen && ne == 0)) {
|
||||
VALUE str = rb_str_new2(orig_szVal);
|
||||
rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str);
|
||||
}
|
||||
|
||||
nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */
|
||||
/* units for szVal[] */
|
||||
if (mx == 0) mx = 1;
|
||||
|
@ -4107,7 +4190,7 @@ VpAddSub(Real *c, Real *a, Real *b, int operation)
|
|||
}
|
||||
#endif /* BIGDECIMAL_DEBUG */
|
||||
|
||||
if (!VpIsDefOP(c, a, b, (operation > 0) ? 1 : 2)) return 0; /* No significant digits */
|
||||
if (!VpIsDefOP(c, a, b, (operation > 0) ? OP_SW_ADD : OP_SW_SUB)) return 0; /* No significant digits */
|
||||
|
||||
/* check if a or b is zero */
|
||||
if (VpIsZero(a)) {
|
||||
|
@ -4563,7 +4646,7 @@ VpMult(Real *c, Real *a, Real *b)
|
|||
}
|
||||
#endif /* BIGDECIMAL_DEBUG */
|
||||
|
||||
if (!VpIsDefOP(c, a, b, 3)) return 0; /* No significant digit */
|
||||
if (!VpIsDefOP(c, a, b, OP_SW_MULT)) return 0; /* No significant digit */
|
||||
|
||||
if (VpIsZero(a) || VpIsZero(b)) {
|
||||
/* at least a or b is zero */
|
||||
|
@ -4675,7 +4758,7 @@ Exit:
|
|||
/*
|
||||
* c = a / b, remainder = r
|
||||
*/
|
||||
VP_EXPORT size_t
|
||||
VP_EXPORT size_t
|
||||
VpDivd(Real *c, Real *r, Real *a, Real *b)
|
||||
{
|
||||
size_t word_a, word_b, word_c, word_r;
|
||||
|
@ -4693,14 +4776,14 @@ VpDivd(Real *c, Real *r, Real *a, Real *b)
|
|||
#endif /*BIGDECIMAL_DEBUG */
|
||||
|
||||
VpSetNaN(r);
|
||||
if (!VpIsDefOP(c, a, b, 4)) goto Exit;
|
||||
if (!VpIsDefOP(c, a, b, OP_SW_DIV)) goto Exit;
|
||||
if (VpIsZero(a) && VpIsZero(b)) {
|
||||
VpSetNaN(c);
|
||||
return VpException(VP_EXCEPTION_NaN, "(VpDivd) 0/0 not defined(NaN)", 0);
|
||||
return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0);
|
||||
}
|
||||
if (VpIsZero(b)) {
|
||||
VpSetInf(c, VpGetSign(a) * VpGetSign(b));
|
||||
return VpException(VP_EXCEPTION_ZERODIVIDE, "(VpDivd) Divide by zero", 0);
|
||||
return VpException(VP_EXCEPTION_ZERODIVIDE, "Divide by zero", 0);
|
||||
}
|
||||
if (VpIsZero(a)) {
|
||||
/* numerator a is zero */
|
||||
|
@ -5053,7 +5136,7 @@ VPrint(FILE *fp, const char *cntl_chr, Real *a)
|
|||
nc += 9;
|
||||
}
|
||||
else if (!VpIsZero(a)) {
|
||||
if (VpGetSign(a) < 0) {
|
||||
if (BIGDECIMAL_NEGATIVE_P(a)) {
|
||||
fprintf(fp, "-");
|
||||
++nc;
|
||||
}
|
||||
|
@ -5142,7 +5225,7 @@ VpFormatSt(char *psz, size_t fFmt)
|
|||
if (!ch) break;
|
||||
if (ISSPACE(ch) || ch=='-' || ch=='+') continue;
|
||||
if (ch == '.') { nf = 0; continue; }
|
||||
if (ch == 'E') break;
|
||||
if (ch == 'E' || ch == 'e') break;
|
||||
|
||||
if (++nf > fFmt) {
|
||||
memmove(psz + i + 1, psz + i, ie - i + 1);
|
||||
|
@ -5191,7 +5274,7 @@ VpSzMantissa(Real *a,char *psz)
|
|||
|
||||
ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */
|
||||
if (!VpIsZero(a)) {
|
||||
if (VpGetSign(a) < 0) *psz++ = '-';
|
||||
if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-';
|
||||
n = a->Prec;
|
||||
for (i = 0; i < n; ++i) {
|
||||
m = BASE1;
|
||||
|
@ -5265,7 +5348,7 @@ VpToString(Real *a, char *psz, size_t fFmt, int fPlus)
|
|||
|
||||
ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */
|
||||
|
||||
if (VpGetSign(a) < 0) *psz++ = '-';
|
||||
if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-';
|
||||
else if (fPlus == 1) *psz++ = ' ';
|
||||
else if (fPlus == 2) *psz++ = '+';
|
||||
|
||||
|
@ -5296,7 +5379,7 @@ VpToString(Real *a, char *psz, size_t fFmt, int fPlus)
|
|||
while (psz[-1] == '0') {
|
||||
*(--psz) = 0;
|
||||
}
|
||||
sprintf(psz, "E%"PRIdSIZE, ex);
|
||||
sprintf(psz, "e%"PRIdSIZE, ex);
|
||||
if (fFmt) VpFormatSt(pszSav, fFmt);
|
||||
}
|
||||
|
||||
|
@ -5311,7 +5394,7 @@ VpToFString(Real *a, char *psz, size_t fFmt, int fPlus)
|
|||
|
||||
if (VpToSpecialString(a, psz, fPlus)) return;
|
||||
|
||||
if (VpGetSign(a) < 0) *psz++ = '-';
|
||||
if (BIGDECIMAL_NEGATIVE_P(a)) *psz++ = '-';
|
||||
else if (fPlus == 1) *psz++ = ' ';
|
||||
else if (fPlus == 2) *psz++ = '+';
|
||||
|
||||
|
@ -5733,21 +5816,22 @@ VpSqrt(Real *y, Real *x)
|
|||
ssize_t nr;
|
||||
double val;
|
||||
|
||||
/* Zero, NaN or Infinity ? */
|
||||
if (!VpHasVal(x)) {
|
||||
if (VpIsZero(x) || VpGetSign(x) > 0) {
|
||||
VpAsgn(y,x,1);
|
||||
goto Exit;
|
||||
}
|
||||
VpSetNaN(y);
|
||||
return VpException(VP_EXCEPTION_OP, "(VpSqrt) SQRT(NaN or negative value)", 0);
|
||||
/* Zero or +Infinity ? */
|
||||
if (VpIsZero(x) || VpIsPosInf(x)) {
|
||||
VpAsgn(y,x,1);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
/* Negative ? */
|
||||
if (VpGetSign(x) < 0) {
|
||||
if (BIGDECIMAL_NEGATIVE_P(x)) {
|
||||
VpSetNaN(y);
|
||||
return VpException(VP_EXCEPTION_OP, "(VpSqrt) SQRT(negative value)", 0);
|
||||
return VpException(VP_EXCEPTION_OP, "sqrt of negative value", 0);
|
||||
}
|
||||
|
||||
/* NaN ? */
|
||||
if (VpIsNaN(x)) {
|
||||
VpSetNaN(y);
|
||||
return VpException(VP_EXCEPTION_OP, "sqrt of 'NaN'(Not a Number)", 0);
|
||||
}
|
||||
|
||||
/* One ? */
|
||||
|
@ -5938,10 +6022,10 @@ VpMidRound(Real *y, unsigned short f, ssize_t nf)
|
|||
if (v > 5 || (v == 5 && fracf_1further)) ++div;
|
||||
break;
|
||||
case VP_ROUND_CEIL:
|
||||
if (fracf && (VpGetSign(y) > 0)) ++div;
|
||||
if (fracf && BIGDECIMAL_POSITIVE_P(y)) ++div;
|
||||
break;
|
||||
case VP_ROUND_FLOOR:
|
||||
if (fracf && (VpGetSign(y) < 0)) ++div;
|
||||
if (fracf && BIGDECIMAL_NEGATIVE_P(y)) ++div;
|
||||
break;
|
||||
case VP_ROUND_HALF_EVEN: /* Banker's rounding */
|
||||
if (v > 5) ++div;
|
||||
|
@ -6060,10 +6144,10 @@ VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v)
|
|||
if (v >= 6) f = 1;
|
||||
break;
|
||||
case VP_ROUND_CEIL:
|
||||
if (v && (VpGetSign(c) > 0)) f = 1;
|
||||
if (v && BIGDECIMAL_POSITIVE_P(c)) f = 1;
|
||||
break;
|
||||
case VP_ROUND_FLOOR:
|
||||
if (v && (VpGetSign(c) < 0)) f = 1;
|
||||
if (v && BIGDECIMAL_NEGATIVE_P(c)) f = 1;
|
||||
break;
|
||||
case VP_ROUND_HALF_EVEN: /* Banker's rounding */
|
||||
/* as per VP_ROUND_HALF_DOWN, because this is the last digit of precision,
|
||||
|
@ -6200,7 +6284,7 @@ VpPower(Real *y, Real *x, SIGNED_VALUE n)
|
|||
if (x->exponent == 1 && x->Prec == 1 && x->frac[0] == 1) {
|
||||
/* abs(x) = 1 */
|
||||
VpSetOne(y);
|
||||
if (VpGetSign(x) > 0) goto Exit;
|
||||
if (BIGDECIMAL_POSITIVE_P(x)) goto Exit;
|
||||
if ((n % 2) == 0) goto Exit;
|
||||
VpSetSign(y, -1);
|
||||
goto Exit;
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
# -*- ruby -*-
|
||||
_VERSION = "1.2.8"
|
||||
date = %w$Date:: $[1]
|
||||
# coding: utf-8
|
||||
_VERSION = '1.3.0.pre'
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "bigdecimal"
|
||||
s.version = _VERSION
|
||||
s.date = date
|
||||
s.license = 'ruby'
|
||||
s.summary = "Arbitrary-precision decimal floating-point number library."
|
||||
s.homepage = "https://www.ruby-lang.org"
|
||||
s.email = "mrkn@mrkn.jp"
|
||||
s.description = "This library provides arbitrary-precision decimal floating-point number class."
|
||||
s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"]
|
||||
s.require_path = %[lib]
|
||||
s.files = %w[
|
||||
s.name = "bigdecimal"
|
||||
s.version = _VERSION
|
||||
s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"]
|
||||
s.email = ["mrkn@mrkn.jp"]
|
||||
|
||||
s.summary = "Arbitrary-precision decimal floating-point number library."
|
||||
s.description = "This library provides arbitrary-precision decimal floating-point number class."
|
||||
s.homepage = "https://github.com/ruby/bigdecimal"
|
||||
s.license = "ruby"
|
||||
|
||||
s.require_paths = %w[lib]
|
||||
s.extensions = %w[ext/bigdecimal/extconf.rb]
|
||||
s.files = %w[
|
||||
bigdecimal.gemspec
|
||||
bigdecimal.c
|
||||
bigdecimal.h
|
||||
depend extconf.rb
|
||||
ext/bigdecimal/bigdecimal.c
|
||||
ext/bigdecimal/bigdecimal.h
|
||||
ext/bigdecimal/depend
|
||||
ext/bigdecimal/extconf.rb
|
||||
lib/bigdecimal/jacobian.rb
|
||||
lib/bigdecimal/ludcmp.rb
|
||||
lib/bigdecimal/math.rb
|
||||
|
@ -27,5 +29,8 @@ Gem::Specification.new do |s|
|
|||
sample/nlsolve.rb
|
||||
sample/pi.rb
|
||||
]
|
||||
s.extensions = %w[extconf.rb]
|
||||
|
||||
s.add_development_dependency "rake", "~> 10.0"
|
||||
s.add_development_dependency "rake-compiler", "~> 0.9"
|
||||
s.add_development_dependency "minitest", "~> 4.7.5"
|
||||
end
|
||||
|
|
|
@ -90,6 +90,56 @@ llabs(LONG_LONG const x)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FINITE
|
||||
static int
|
||||
finite(double)
|
||||
{
|
||||
return !isnan(n) && !isinf(n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef isfinite
|
||||
# ifndef HAVE_ISFINITE
|
||||
# define HAVE_ISFINITE 1
|
||||
# define isfinite(x) finite(x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef FIX_CONST_VALUE_PTR
|
||||
# if defined(__fcc__) || defined(__fcc_version) || \
|
||||
defined(__FCC__) || defined(__FCC_VERSION)
|
||||
/* workaround for old version of Fujitsu C Compiler (fcc) */
|
||||
# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
|
||||
# else
|
||||
# define FIX_CONST_VALUE_PTR(x) (x)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RB_ARRAY_CONST_PTR
|
||||
static inline const VALUE *
|
||||
rb_array_const_ptr(VALUE a)
|
||||
{
|
||||
return FIX_CONST_VALUE_PTR((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ?
|
||||
RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef RARRAY_CONST_PTR
|
||||
# define RARRAY_CONST_PTR(a) rb_array_const_ptr(a)
|
||||
#endif
|
||||
|
||||
#ifndef RARRAY_AREF
|
||||
# define RARRAY_AREF(a, i) (RARRAY_CONST_PTR(a)[i])
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_RB_SYM2STR
|
||||
static inline VALUE
|
||||
rb_sym2str(VALUE sym)
|
||||
{
|
||||
return rb_id2str(SYM2ID(sym));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef vabs
|
||||
# undef vabs
|
||||
#endif
|
||||
|
@ -182,11 +232,11 @@ extern VALUE rb_cBigDecimal;
|
|||
typedef struct {
|
||||
VALUE obj; /* Back pointer(VALUE) for Ruby object. */
|
||||
size_t MaxPrec; /* Maximum precision size */
|
||||
/* This is the actual size of pfrac[] */
|
||||
/* This is the actual size of frac[] */
|
||||
/*(frac[0] to frac[MaxPrec] are available). */
|
||||
size_t Prec; /* Current precision size. */
|
||||
/* This indicates how much the. */
|
||||
/* the array frac[] is actually used. */
|
||||
/* This indicates how much the */
|
||||
/* array frac[] is actually used. */
|
||||
SIGNED_VALUE exponent; /* Exponent part. */
|
||||
short sign; /* Attributes of the value. */
|
||||
/*
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# AUTOGENERATED DEPENDENCIES START
|
||||
bigdecimal.o: $(RUBY_EXTCONF_H)
|
||||
bigdecimal.o: $(arch_hdrdir)/ruby/config.h
|
||||
bigdecimal.o: $(hdrdir)/ruby/backward.h
|
||||
bigdecimal.o: $(hdrdir)/ruby/defines.h
|
||||
bigdecimal.o: $(hdrdir)/ruby/intern.h
|
||||
bigdecimal.o: $(hdrdir)/ruby/missing.h
|
||||
|
|
|
@ -1,11 +1,30 @@
|
|||
# frozen_string_literal: false
|
||||
require 'mkmf'
|
||||
|
||||
alias __have_macro__ have_macro
|
||||
|
||||
have_func("labs", "stdlib.h")
|
||||
have_func("llabs", "stdlib.h")
|
||||
have_func("finite", "math.h")
|
||||
have_func("isfinite", "math.h")
|
||||
|
||||
have_type("struct RRational", "ruby.h")
|
||||
have_func("rb_rational_num", "ruby.h")
|
||||
have_func("rb_rational_den", "ruby.h")
|
||||
have_func("rb_array_const_ptr", "ruby.h")
|
||||
have_func("rb_sym2str", "ruby.h")
|
||||
|
||||
have_macro("FIX_CONST_VALUE_PTR", "ruby.h")
|
||||
have_macro("RARRAY_CONST_PTR", "ruby.h")
|
||||
have_macro("RARRAY_AREF", "ruby.h")
|
||||
|
||||
create_makefile('bigdecimal')
|
||||
|
||||
# Add additional dependencies
|
||||
open('Makefile', 'a') do |io|
|
||||
if RUBY_VERSION >= '2.4'
|
||||
io.puts <<-MAKEFILE
|
||||
bigdecimal.o: $(hdrdir)/ruby/backward.h
|
||||
MAKEFILE
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: false
|
||||
# BigDecimal extends the native Integer class to provide the #to_d method.
|
||||
#
|
||||
# When you require the BigDecimal library in your application, this methodwill
|
||||
# When you require the BigDecimal library in your application, this method will
|
||||
# be available on Integer objects.
|
||||
class Integer < Numeric
|
||||
# call-seq:
|
||||
|
|
|
@ -53,17 +53,16 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(1, BigDecimal("1"))
|
||||
assert_equal(1, BigDecimal("1", 1))
|
||||
assert_raise(ArgumentError) { BigDecimal("1", -1) }
|
||||
assert_raise(ArgumentError) { BigDecimal(4.2) }
|
||||
begin
|
||||
BigDecimal(4.2)
|
||||
rescue ArgumentError => error
|
||||
assert_match(/Float/, error.message)
|
||||
end
|
||||
assert_raise(ArgumentError) { BigDecimal(42.quo(7)) }
|
||||
begin
|
||||
BigDecimal(42.quo(7))
|
||||
rescue ArgumentError => error
|
||||
assert_match(/Rational/, error.message)
|
||||
end
|
||||
|
||||
def test_global_new_with_invalid_string
|
||||
[
|
||||
'', '.', 'e1', 'd1', '.e', '.d', '1.e', '1.d', '.1e', '.1d',
|
||||
'invlaid value'
|
||||
].each do |invalid_string|
|
||||
assert_raise_with_message(ArgumentError, %Q[invalid value for BigDecimal(): "#{invalid_string}"]) do
|
||||
BigDecimal(invalid_string)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -77,18 +76,28 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
def test_global_new_with_rational
|
||||
assert_equal(BigDecimal("0.333333333333333333333"), BigDecimal(1.quo(3), 21))
|
||||
assert_equal(BigDecimal("-0.333333333333333333333"), BigDecimal(-1.quo(3), 21))
|
||||
assert_raise(ArgumentError) { BigDecimal(1.quo(3)) }
|
||||
assert_raise_with_message(ArgumentError, "can't omit precision for a Rational.") { BigDecimal(42.quo(7)) }
|
||||
end
|
||||
|
||||
def test_global_new_with_float
|
||||
assert_equal(BigDecimal("0.1235"), BigDecimal(0.1234567, 4))
|
||||
assert_equal(BigDecimal("-0.1235"), BigDecimal(-0.1234567, 4))
|
||||
assert_raise(ArgumentError) { BigDecimal(0.1) }
|
||||
assert_raise_with_message(ArgumentError, "can't omit precision for a Float.") { BigDecimal(4.2) }
|
||||
assert_raise(ArgumentError) { BigDecimal(0.1, Float::DIG + 2) }
|
||||
assert_nothing_raised { BigDecimal(0.1, Float::DIG + 1) }
|
||||
|
||||
bug9214 = '[ruby-core:58858]'
|
||||
assert_equal(BigDecimal(-0.0, Float::DIG).sign, -1, bug9214)
|
||||
|
||||
BigDecimal.save_exception_mode do
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert_nan(BigDecimal(Float::NAN))
|
||||
end
|
||||
BigDecimal.save_exception_mode do
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
assert_positive_infinite(BigDecimal(Float::INFINITY))
|
||||
assert_negative_infinite(BigDecimal(-Float::INFINITY))
|
||||
end
|
||||
end
|
||||
|
||||
def test_global_new_with_big_decimal
|
||||
|
@ -116,15 +125,16 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(1, BigDecimal.new("1", 1))
|
||||
assert_equal(1, BigDecimal.new(" 1 "))
|
||||
assert_equal(111, BigDecimal.new("1_1_1_"))
|
||||
assert_equal(0, BigDecimal.new("_1_1_1"))
|
||||
assert_equal(10**(-1), BigDecimal.new("1E-1"), '#4825')
|
||||
|
||||
assert_raise(ArgumentError, /"_1_1_1"/) { BigDecimal.new("_1_1_1") }
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert_equal( 1, BigDecimal.new("Infinity").infinite?)
|
||||
assert_equal(-1, BigDecimal.new("-Infinity").infinite?)
|
||||
assert_equal(true, BigDecimal.new("NaN").nan?)
|
||||
assert_equal( 1, BigDecimal.new("1E1111111111111111111").infinite?)
|
||||
assert_positive_infinite(BigDecimal.new("Infinity"))
|
||||
assert_negative_infinite(BigDecimal.new("-Infinity"))
|
||||
assert_nan(BigDecimal.new("NaN"))
|
||||
assert_positive_infinite(BigDecimal.new("1E1111111111111111111"))
|
||||
end
|
||||
|
||||
def test_new_with_integer
|
||||
|
@ -392,14 +402,28 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_zero_p
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
|
||||
assert_equal(true, BigDecimal.new("0").zero?)
|
||||
assert_equal(true, BigDecimal.new("-0").zero?)
|
||||
assert_equal(false, BigDecimal.new("1").zero?)
|
||||
assert_equal(true, BigDecimal.new("0E200000000000000").zero?)
|
||||
assert_equal(false, BigDecimal.new("Infinity").zero?)
|
||||
assert_equal(false, BigDecimal.new("-Infinity").zero?)
|
||||
assert_equal(false, BigDecimal.new("NaN").zero?)
|
||||
end
|
||||
|
||||
def test_nonzero_p
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
|
||||
assert_equal(nil, BigDecimal.new("0").nonzero?)
|
||||
assert_equal(nil, BigDecimal.new("-0").nonzero?)
|
||||
assert_equal(BigDecimal.new("1"), BigDecimal.new("1").nonzero?)
|
||||
assert_positive_infinite(BigDecimal.new("Infinity").nonzero?)
|
||||
assert_negative_infinite(BigDecimal.new("-Infinity").nonzero?)
|
||||
assert_nan(BigDecimal.new("NaN").nonzero?)
|
||||
end
|
||||
|
||||
def test_double_fig
|
||||
|
@ -457,18 +481,8 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert_equal(nil, BigDecimal.new("NaN") <=> n1)
|
||||
assert_equal(false, BigDecimal.new("NaN") > n1)
|
||||
end
|
||||
|
||||
def test_cmp_float_nan
|
||||
assert_equal(nil, BigDecimal.new("1") <=> Float::NAN)
|
||||
end
|
||||
|
||||
def test_cmp_float_pos_inf
|
||||
assert_equal(-1, BigDecimal.new("1") <=> Float::INFINITY)
|
||||
end
|
||||
|
||||
def test_cmp_float_neg_inf
|
||||
assert_equal(+1, BigDecimal.new("1") <=> -Float::INFINITY)
|
||||
assert_equal(nil, BigDecimal.new("NaN") <=> BigDecimal.new("NaN"))
|
||||
assert_equal(false, BigDecimal.new("NaN") == BigDecimal.new("NaN"))
|
||||
end
|
||||
|
||||
def test_cmp_failing_coercion
|
||||
|
@ -493,6 +507,11 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_operator(n2, :>, o1)
|
||||
assert_operator(n2, :>=, o1)
|
||||
assert_operator(n1, :>=, 1)
|
||||
|
||||
bug10109 = '[ruby-core:64190]'
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
assert_operator(BigDecimal(0), :<, Float::INFINITY, bug10109)
|
||||
assert_operator(Float::INFINITY, :>, BigDecimal(0), bug10109)
|
||||
end
|
||||
|
||||
def test_cmp_bignum
|
||||
|
@ -582,7 +601,7 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(0.0, x.to_f)
|
||||
assert_equal( 1.0 / 0.0, ( 1 / x).to_f)
|
||||
assert_equal(-1.0 / 0.0, (-1 / x).to_f)
|
||||
assert_equal(true, ( 0 / x).to_f.nan?)
|
||||
assert_nan(( 0 / x).to_f)
|
||||
x = BigDecimal.new("1")
|
||||
assert_equal(1.0, x.to_f)
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
|
@ -632,6 +651,22 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(-0.0, BigDecimal('-10e-325').to_f)
|
||||
end
|
||||
|
||||
def test_to_r
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
|
||||
x = BigDecimal.new("0")
|
||||
assert_kind_of(Rational, x.to_r)
|
||||
assert_equal(0, x.to_r)
|
||||
assert_raise(FloatDomainError) {( 1 / x).to_r}
|
||||
assert_raise(FloatDomainError) {(-1 / x).to_r}
|
||||
assert_raise(FloatDomainError) {( 0 / x).to_r}
|
||||
|
||||
assert_equal(1, BigDecimal.new("1").to_r)
|
||||
assert_equal(Rational(3, 2), BigDecimal.new("1.5").to_r)
|
||||
assert_equal((2**100).to_r, BigDecimal.new((2**100).to_s).to_r)
|
||||
end
|
||||
|
||||
def test_coerce
|
||||
a, b = BigDecimal.new("1").coerce(1.0)
|
||||
assert_instance_of(BigDecimal, a)
|
||||
|
@ -654,6 +689,18 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(x, x.send(:+@))
|
||||
end
|
||||
|
||||
def test_neg
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
|
||||
assert_equal(BigDecimal.new("-1"), BigDecimal.new("1").send(:-@))
|
||||
assert_equal(BigDecimal.new("-0"), BigDecimal.new("0").send(:-@))
|
||||
assert_equal(BigDecimal.new("0"), BigDecimal.new("-0").send(:-@))
|
||||
assert_equal(BigDecimal.new("-Infinity"), BigDecimal.new("Infinity").send(:-@))
|
||||
assert_equal(BigDecimal.new("Infinity"), BigDecimal.new("-Infinity").send(:-@))
|
||||
assert_equal(true, BigDecimal.new("NaN").send(:-@).nan?)
|
||||
end
|
||||
|
||||
def test_add
|
||||
x = BigDecimal.new("1")
|
||||
assert_equal(BigDecimal.new("2"), x + x)
|
||||
|
@ -666,6 +713,14 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(BigDecimal.new((2**100+1).to_s), x + 1)
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
inf = BigDecimal("Infinity")
|
||||
neginf = BigDecimal("-Infinity")
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
|
||||
assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf + inf }
|
||||
assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf + neginf }
|
||||
end
|
||||
|
||||
def test_sub
|
||||
|
@ -680,6 +735,14 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(BigDecimal.new((2**100-1).to_s), x - 1)
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
inf = BigDecimal("Infinity")
|
||||
neginf = BigDecimal("-Infinity")
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
|
||||
assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf - neginf }
|
||||
assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf - inf }
|
||||
end
|
||||
|
||||
def test_sub_with_float
|
||||
|
@ -696,6 +759,14 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(x, (x * 1).to_i)
|
||||
assert_equal(x, (BigDecimal("1") * x).to_i)
|
||||
assert_equal(BigDecimal.new((2**200).to_s), (x * x).to_i)
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
inf = BigDecimal("Infinity")
|
||||
neginf = BigDecimal("-Infinity")
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
|
||||
assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { inf * inf }
|
||||
assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { neginf * inf }
|
||||
end
|
||||
|
||||
def test_mult_with_float
|
||||
|
@ -723,6 +794,17 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(BigDecimal('1486.868686869'), BigDecimal('1472.0') / BigDecimal('0.99'), '[ruby-core:59365] [#9316]')
|
||||
|
||||
assert_equal(4.124045235, BigDecimal('0.9932') / (700 * BigDecimal('0.344045') / BigDecimal('1000.0')), '[#9305]')
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
assert_positive_zero(BigDecimal.new("1.0") / BigDecimal.new("Infinity"))
|
||||
assert_negative_zero(BigDecimal.new("-1.0") / BigDecimal.new("Infinity"))
|
||||
assert_negative_zero(BigDecimal.new("1.0") / BigDecimal.new("-Infinity"))
|
||||
assert_positive_zero(BigDecimal.new("-1.0") / BigDecimal.new("-Infinity"))
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
|
||||
assert_raise_with_message(FloatDomainError, "Computation results to 'Infinity'") { BigDecimal.new("1") / 0 }
|
||||
assert_raise_with_message(FloatDomainError, "Computation results to '-Infinity'") { BigDecimal.new("-1") / 0 }
|
||||
end
|
||||
|
||||
def test_div_with_float
|
||||
|
@ -807,12 +889,6 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
assert_equal(0, BigDecimal("0").div(BigDecimal("Infinity")))
|
||||
end
|
||||
|
||||
x = BigDecimal.new("1")
|
||||
y = BigDecimal.new("0.22")
|
||||
(2..20).each do |i|
|
||||
assert_equal ("0."+"45"*(i/2)+"5"*(i%2)+"E1"), x.div(y, i).to_s, "#{i}"
|
||||
end
|
||||
end
|
||||
|
||||
def test_abs_bigdecimal
|
||||
|
@ -822,9 +898,18 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(1267650600228229401496703205376, x.abs)
|
||||
x = BigDecimal.new("0")
|
||||
assert_equal(0, x.abs)
|
||||
x = BigDecimal.new("-0")
|
||||
assert_equal(0, x.abs)
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
x = BigDecimal.new("Infinity")
|
||||
assert_equal(BigDecimal.new("Infinity"), x.abs)
|
||||
x = BigDecimal.new("-Infinity")
|
||||
assert_equal(BigDecimal.new("Infinity"), x.abs)
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
x = BigDecimal.new("NaN")
|
||||
assert_equal(true, x.abs.nan?)
|
||||
assert_nan(x.abs)
|
||||
end
|
||||
|
||||
def test_sqrt_bigdecimal
|
||||
|
@ -837,16 +922,19 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(true, (x.sqrt(200) - y).abs < BigDecimal("1E#{e-200}"))
|
||||
assert_equal(true, (x.sqrt(300) - y).abs < BigDecimal("1E#{e-300}"))
|
||||
x = BigDecimal.new("-" + (2**100).to_s)
|
||||
assert_raise(FloatDomainError) { x.sqrt(1) }
|
||||
assert_raise_with_message(FloatDomainError, "sqrt of negative value") { x.sqrt(1) }
|
||||
x = BigDecimal.new((2**200).to_s)
|
||||
assert_equal(2**100, x.sqrt(1))
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert_raise(FloatDomainError) { BigDecimal.new("NaN").sqrt(1) }
|
||||
assert_raise_with_message(FloatDomainError, "sqrt of 'NaN'(Not a Number)") { BigDecimal.new("NaN").sqrt(1) }
|
||||
assert_raise_with_message(FloatDomainError, "sqrt of negative value") { BigDecimal.new("-Infinity").sqrt(1) }
|
||||
|
||||
assert_equal(0, BigDecimal.new("0").sqrt(1))
|
||||
assert_equal(0, BigDecimal.new("-0").sqrt(1))
|
||||
assert_equal(1, BigDecimal.new("1").sqrt(1))
|
||||
assert_positive_infinite(BigDecimal.new("Infinity").sqrt(1))
|
||||
end
|
||||
|
||||
def test_sqrt_5266
|
||||
|
@ -866,6 +954,7 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
def test_fix
|
||||
x = BigDecimal.new("1.1")
|
||||
assert_equal(1, x.fix)
|
||||
assert_kind_of(BigDecimal, x.fix)
|
||||
end
|
||||
|
||||
def test_frac
|
||||
|
@ -873,7 +962,7 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal(0.1, x.frac)
|
||||
assert_equal(0.1, BigDecimal.new("0.1").frac)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert_equal(true, BigDecimal.new("NaN").frac.nan?)
|
||||
assert_nan(BigDecimal.new("NaN").frac)
|
||||
end
|
||||
|
||||
def test_round
|
||||
|
@ -921,6 +1010,75 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_round_half_even
|
||||
assert_equal(BigDecimal('12.0'), BigDecimal('12.5').round(half: :even))
|
||||
assert_equal(BigDecimal('14.0'), BigDecimal('13.5').round(half: :even))
|
||||
|
||||
assert_equal(BigDecimal('2.2'), BigDecimal('2.15').round(1, half: :even))
|
||||
assert_equal(BigDecimal('2.2'), BigDecimal('2.25').round(1, half: :even))
|
||||
assert_equal(BigDecimal('2.4'), BigDecimal('2.35').round(1, half: :even))
|
||||
|
||||
assert_equal(BigDecimal('-2.2'), BigDecimal('-2.15').round(1, half: :even))
|
||||
assert_equal(BigDecimal('-2.2'), BigDecimal('-2.25').round(1, half: :even))
|
||||
assert_equal(BigDecimal('-2.4'), BigDecimal('-2.35').round(1, half: :even))
|
||||
|
||||
assert_equal(BigDecimal('7.1364'), BigDecimal('7.13645').round(4, half: :even))
|
||||
assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :even))
|
||||
assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :even))
|
||||
|
||||
assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.13645').round(4, half: :even))
|
||||
assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :even))
|
||||
assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :even))
|
||||
end
|
||||
|
||||
def test_round_half_up
|
||||
assert_equal(BigDecimal('13.0'), BigDecimal('12.5').round(half: :up))
|
||||
assert_equal(BigDecimal('14.0'), BigDecimal('13.5').round(half: :up))
|
||||
|
||||
assert_equal(BigDecimal('2.2'), BigDecimal('2.15').round(1, half: :up))
|
||||
assert_equal(BigDecimal('2.3'), BigDecimal('2.25').round(1, half: :up))
|
||||
assert_equal(BigDecimal('2.4'), BigDecimal('2.35').round(1, half: :up))
|
||||
|
||||
assert_equal(BigDecimal('-2.2'), BigDecimal('-2.15').round(1, half: :up))
|
||||
assert_equal(BigDecimal('-2.3'), BigDecimal('-2.25').round(1, half: :up))
|
||||
assert_equal(BigDecimal('-2.4'), BigDecimal('-2.35').round(1, half: :up))
|
||||
|
||||
assert_equal(BigDecimal('7.1365'), BigDecimal('7.13645').round(4, half: :up))
|
||||
assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :up))
|
||||
assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :up))
|
||||
|
||||
assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.13645').round(4, half: :up))
|
||||
assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :up))
|
||||
assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :up))
|
||||
end
|
||||
|
||||
def test_round_half_down
|
||||
assert_equal(BigDecimal('12.0'), BigDecimal('12.5').round(half: :down))
|
||||
assert_equal(BigDecimal('13.0'), BigDecimal('13.5').round(half: :down))
|
||||
|
||||
assert_equal(BigDecimal('2.1'), BigDecimal('2.15').round(1, half: :down))
|
||||
assert_equal(BigDecimal('2.2'), BigDecimal('2.25').round(1, half: :down))
|
||||
assert_equal(BigDecimal('2.3'), BigDecimal('2.35').round(1, half: :down))
|
||||
|
||||
assert_equal(BigDecimal('-2.1'), BigDecimal('-2.15').round(1, half: :down))
|
||||
assert_equal(BigDecimal('-2.2'), BigDecimal('-2.25').round(1, half: :down))
|
||||
assert_equal(BigDecimal('-2.3'), BigDecimal('-2.35').round(1, half: :down))
|
||||
|
||||
assert_equal(BigDecimal('7.1364'), BigDecimal('7.13645').round(4, half: :down))
|
||||
assert_equal(BigDecimal('7.1365'), BigDecimal('7.1364501').round(4, half: :down))
|
||||
assert_equal(BigDecimal('7.1364'), BigDecimal('7.1364499').round(4, half: :down))
|
||||
|
||||
assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.13645').round(4, half: :down))
|
||||
assert_equal(BigDecimal('-7.1365'), BigDecimal('-7.1364501').round(4, half: :down))
|
||||
assert_equal(BigDecimal('-7.1364'), BigDecimal('-7.1364499').round(4, half: :down))
|
||||
end
|
||||
|
||||
def test_round_half_invalid_option
|
||||
assert_raise_with_message(ArgumentError, "invalid rounding mode: invalid") { BigDecimal('12.5').round(half: :invalid) }
|
||||
assert_raise_with_message(ArgumentError, "invalid rounding mode: invalid") { BigDecimal('2.15').round(1, half: :invalid) }
|
||||
assert_raise_with_message(ArgumentError, "invalid rounding mode: nil") { BigDecimal('12.5').round(half: nil) }
|
||||
end
|
||||
|
||||
def test_truncate
|
||||
assert_equal(3, BigDecimal.new("3.14159").truncate)
|
||||
assert_equal(8, BigDecimal.new("8.7").truncate)
|
||||
|
@ -946,8 +1104,8 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
assert_equal('-123.45678 90123 45678 9', BigDecimal.new('-123.45678901234567890').to_s('5F'))
|
||||
assert_equal('+123.45678901 23456789', BigDecimal.new('123.45678901234567890').to_s('+8F'))
|
||||
assert_equal(' 123.4567890123456789', BigDecimal.new('123.45678901234567890').to_s(' F'))
|
||||
assert_equal('0.1234567890123456789E3', BigDecimal.new('123.45678901234567890').to_s)
|
||||
assert_equal('0.12345 67890 12345 6789E3', BigDecimal.new('123.45678901234567890').to_s(5))
|
||||
assert_equal('0.1234567890123456789e3', BigDecimal.new('123.45678901234567890').to_s)
|
||||
assert_equal('0.12345 67890 12345 6789e3', BigDecimal.new('123.45678901234567890').to_s(5))
|
||||
end
|
||||
|
||||
def test_split
|
||||
|
@ -969,9 +1127,9 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_inspect
|
||||
x = BigDecimal.new("1234.5678")
|
||||
prec, maxprec = x.precs
|
||||
assert_match(/^#<BigDecimal:[0-9a-f]+,'0.12345678E4',#{prec}\(#{maxprec}\)>$/, x.inspect)
|
||||
assert_equal("0.123456789012e0", BigDecimal.new("0.123456789012").inspect)
|
||||
assert_equal("0.123456789012e4", BigDecimal.new("1234.56789012").inspect)
|
||||
assert_equal("0.123456789012e-4", BigDecimal.new("0.0000123456789012").inspect)
|
||||
end
|
||||
|
||||
def test_power
|
||||
|
@ -1220,23 +1378,23 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
inf = BigDecimal.new("Infinity")
|
||||
|
||||
assert_equal(inf, inf + inf)
|
||||
assert_equal(true, (inf + (-inf)).nan?)
|
||||
assert_equal(true, (inf - inf).nan?)
|
||||
assert_nan((inf + (-inf)))
|
||||
assert_nan((inf - inf))
|
||||
assert_equal(inf, inf - (-inf))
|
||||
assert_equal(inf, inf * inf)
|
||||
assert_equal(true, (inf / inf).nan?)
|
||||
assert_nan((inf / inf))
|
||||
|
||||
assert_equal(inf, inf + 1)
|
||||
assert_equal(inf, inf - 1)
|
||||
assert_equal(inf, inf * 1)
|
||||
assert_equal(true, (inf * 0).nan?)
|
||||
assert_nan((inf * 0))
|
||||
assert_equal(inf, inf / 1)
|
||||
|
||||
assert_equal(inf, 1 + inf)
|
||||
assert_equal(-inf, 1 - inf)
|
||||
assert_equal(inf, 1 * inf)
|
||||
assert_equal(-inf, -1 * inf)
|
||||
assert_equal(true, (0 * inf).nan?)
|
||||
assert_nan((0 * inf))
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (1 / inf).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (-1 / inf).sign)
|
||||
end
|
||||
|
@ -1306,14 +1464,14 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_INFINITY
|
||||
assert(BigDecimal::INFINITY.infinite?, "BigDecimal::INFINITY is not a infinity")
|
||||
assert_positive_infinite(BigDecimal::INFINITY)
|
||||
end
|
||||
|
||||
def test_NAN
|
||||
assert(BigDecimal::NAN.nan?, "BigDecimal::NAN is not NaN")
|
||||
assert_nan(BigDecimal::NAN)
|
||||
end
|
||||
|
||||
def test_exp_with_zerp_precision
|
||||
def test_exp_with_zero_precision
|
||||
assert_raise(ArgumentError) do
|
||||
BigMath.exp(1, 0)
|
||||
end
|
||||
|
@ -1342,14 +1500,14 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
BigDecimal.save_exception_mode do
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
assert(BigMath.exp(BigDecimal::INFINITY, 20) > 0)
|
||||
assert(BigMath.exp(BigDecimal::INFINITY, 20).infinite?)
|
||||
assert_positive_infinite(BigMath.exp(BigDecimal::INFINITY, 20))
|
||||
end
|
||||
end
|
||||
|
||||
def test_exp_with_nan
|
||||
BigDecimal.save_exception_mode do
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert(BigMath.exp(BigDecimal::NAN, 20).nan?)
|
||||
assert_nan(BigMath.exp(BigDecimal::NAN, 20))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1470,21 +1628,21 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||
BigDecimal.save_exception_mode do
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false)
|
||||
assert(BigMath.log(BigDecimal::INFINITY, 20) > 0)
|
||||
assert(BigMath.log(BigDecimal::INFINITY, 20).infinite?)
|
||||
assert_positive_infinite(BigMath.log(BigDecimal::INFINITY, 20))
|
||||
end
|
||||
end
|
||||
|
||||
def test_BigMath_log_with_nan
|
||||
BigDecimal.save_exception_mode do
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert(BigMath.log(BigDecimal::NAN, 20).nan?)
|
||||
assert_nan(BigMath.log(BigDecimal::NAN, 20))
|
||||
end
|
||||
end
|
||||
|
||||
def test_BigMath_log_with_float_nan
|
||||
BigDecimal.save_exception_mode do
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert(BigMath.log(Float::NAN, 20).nan?)
|
||||
assert_nan(BigMath.log(Float::NAN, 20))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue