mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/bigdecimal/bigdecimal.c (VpCtoV): big number should result
to infinite. backported from 1.9. * ext/bigdecimal/bigdecimal.c (VpIsRoundMode): rounding mode condition check updated. backported from 1.9. * ext/bigdecimal/bigdecimal.c (VpPower): should handle NaN and Inf. backported from 1.9. * ext/bigdecimal/bigdecimal.c (BigDecimal_DoDivmod): divmod should raise ZeroDivisionError. backported from 1.9. * ext/bigdecimal/bigdecimal.c (BigDecimal_mode): should check exception for VP_EXCEPTION_UNDERFLOW and VP_EXCEPTION_ZERODIVIDE. backported from 1.9. * ext/bigdecimal/bigdecimal.c (VpException): ditto. * ext/bigdecimal/bigdecimal.h (VP_EXCEPTION_ZERODIVIDE): new error code. backported from 1.9. * ext/bigdecimal/bigdecimal.c (BigDecimal_div2, BigDecimal_round, BigDecimal_truncate, BigDecimal_floor, BigDecimal_ceil): eagerly convert bigdecimal to integer. backported from 1.9. * ext/bigdecimal/bigdecimal.c (VpMult): free internal Real. backported from 1.9. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@23664 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3bb5d07486
commit
1e7898d76a
4 changed files with 784 additions and 20 deletions
30
ChangeLog
30
ChangeLog
|
@ -1,3 +1,33 @@
|
|||
Thu Jun 11 15:05:00 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (VpCtoV): big number should result
|
||||
to infinite. backported from 1.9.
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (VpIsRoundMode): rounding mode
|
||||
condition check updated. backported from 1.9.
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (VpPower): should handle NaN and
|
||||
Inf. backported from 1.9.
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (BigDecimal_DoDivmod): divmod should
|
||||
raise ZeroDivisionError. backported from 1.9.
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (BigDecimal_mode): should check
|
||||
exception for VP_EXCEPTION_UNDERFLOW and VP_EXCEPTION_ZERODIVIDE.
|
||||
backported from 1.9.
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (VpException): ditto.
|
||||
|
||||
* ext/bigdecimal/bigdecimal.h (VP_EXCEPTION_ZERODIVIDE): new error
|
||||
code. backported from 1.9.
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (BigDecimal_div2, BigDecimal_round,
|
||||
BigDecimal_truncate, BigDecimal_floor, BigDecimal_ceil): eagerly convert
|
||||
bigdecimal to integer. backported from 1.9.
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (VpMult): free internal Real.
|
||||
backported from 1.9.
|
||||
|
||||
Thu Jun 11 13:29:16 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* ext/bigdecimal/bigdecimal.c (VpToString): fixed a bug introduced
|
||||
|
|
|
@ -22,7 +22,10 @@
|
|||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include "math.h"
|
||||
#include "version.h"
|
||||
|
||||
#ifdef HAVE_IEEEFP_H
|
||||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
/* #define ENABLE_NUMERIC_STRING */
|
||||
|
||||
|
@ -411,11 +414,22 @@ BigDecimal_mode(int argc, VALUE *argv, VALUE self)
|
|||
VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_INFINITY):
|
||||
(fo&(~VP_EXCEPTION_INFINITY))));
|
||||
}
|
||||
fo = VpGetException();
|
||||
if(f&VP_EXCEPTION_NaN) {
|
||||
VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_NaN):
|
||||
(fo&(~VP_EXCEPTION_NaN))));
|
||||
}
|
||||
fo = VpGetException();
|
||||
if(f&VP_EXCEPTION_UNDERFLOW) {
|
||||
VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_UNDERFLOW):
|
||||
(fo&(~VP_EXCEPTION_UNDERFLOW))));
|
||||
}
|
||||
fo = VpGetException();
|
||||
if(f&VP_EXCEPTION_ZERODIVIDE) {
|
||||
VpSetException((unsigned short)((val==Qtrue)?(fo|VP_EXCEPTION_ZERODIVIDE):
|
||||
(fo&(~VP_EXCEPTION_ZERODIVIDE))));
|
||||
}
|
||||
fo = VpGetException();
|
||||
return INT2FIX(fo);
|
||||
}
|
||||
if(VP_ROUND_MODE==f) {
|
||||
|
@ -956,7 +970,9 @@ BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod)
|
|||
|
||||
if(VpIsNaN(a) || VpIsNaN(b)) goto NaN;
|
||||
if(VpIsInf(a) || VpIsInf(b)) goto NaN;
|
||||
if(VpIsZero(b)) goto NaN;
|
||||
if(VpIsZero(b)) {
|
||||
rb_raise(rb_eZeroDivError, "divided by 0");
|
||||
}
|
||||
if(VpIsZero(a)) {
|
||||
GUARD_OBJ(c,VpCreateRbObject(1, "0"));
|
||||
GUARD_OBJ(d,VpCreateRbObject(1, "0"));
|
||||
|
@ -1113,7 +1129,7 @@ BigDecimal_div2(int argc, VALUE *argv, VALUE self)
|
|||
Real *mod;
|
||||
obj = BigDecimal_DoDivmod(self,b,&div,&mod);
|
||||
if(obj!=(VALUE)0) return obj;
|
||||
return ToValue(div);
|
||||
return BigDecimal_to_i(ToValue(div));
|
||||
} else { /* div in BigDecimal sense */
|
||||
U_LONG ix = (U_LONG)GetPositiveInt(n);
|
||||
if(ix==0) return BigDecimal_div(self,b);
|
||||
|
@ -1311,6 +1327,9 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
|||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||
VpSetPrecLimit(pl);
|
||||
VpActiveRound(c,a,sw,iLoc);
|
||||
if (argc == 0) {
|
||||
return BigDecimal_to_i(ToValue(c));
|
||||
}
|
||||
return ToValue(c);
|
||||
}
|
||||
|
||||
|
@ -1355,6 +1374,9 @@ BigDecimal_truncate(int argc, VALUE *argv, VALUE self)
|
|||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||
VpSetPrecLimit(pl);
|
||||
VpActiveRound(c,a,VP_ROUND_DOWN,iLoc); /* 0: truncate */
|
||||
if (argc == 0) {
|
||||
return BigDecimal_to_i(ToValue(c));
|
||||
}
|
||||
return ToValue(c);
|
||||
}
|
||||
|
||||
|
@ -1415,6 +1437,9 @@ BigDecimal_floor(int argc, VALUE *argv, VALUE self)
|
|||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||
VpSetPrecLimit(pl);
|
||||
VpActiveRound(c,a,VP_ROUND_FLOOR,iLoc);
|
||||
if (argc == 0) {
|
||||
return BigDecimal_to_i(ToValue(c));
|
||||
}
|
||||
return ToValue(c);
|
||||
}
|
||||
|
||||
|
@ -1459,6 +1484,9 @@ BigDecimal_ceil(int argc, VALUE *argv, VALUE self)
|
|||
GUARD_OBJ(c,VpCreateRbObject(mx, "0"));
|
||||
VpSetPrecLimit(pl);
|
||||
VpActiveRound(c,a,VP_ROUND_CEIL,iLoc);
|
||||
if (argc == 0) {
|
||||
return BigDecimal_to_i(ToValue(c));
|
||||
}
|
||||
return ToValue(c);
|
||||
}
|
||||
|
||||
|
@ -1741,7 +1769,7 @@ BigDecimal_new(int argc, VALUE *argv, VALUE self)
|
|||
*
|
||||
* A limit of 0, the default, means no upper limit.
|
||||
*
|
||||
* The limit specified by this method takes priority over any limit
|
||||
* The limit specified by this method takes less priority over any limit
|
||||
* specified to instance methods such as ceil, floor, truncate, or round.
|
||||
*/
|
||||
static VALUE
|
||||
|
@ -1846,7 +1874,7 @@ Init_bigdecimal(void)
|
|||
|
||||
/*
|
||||
* 0x01: Determines what happens when the result of a computation is an
|
||||
* underflow (a result too large to be represented). See BigDecimal.mode.
|
||||
* overflow (a result too large to be represented). See BigDecimal.mode.
|
||||
*/
|
||||
rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW",INT2FIX(VP_EXCEPTION_OVERFLOW));
|
||||
|
||||
|
@ -2097,9 +2125,9 @@ VpGetRoundMode(void)
|
|||
VP_EXPORT int
|
||||
VpIsRoundMode(unsigned long n)
|
||||
{
|
||||
if(n==VP_ROUND_UP || n!=VP_ROUND_DOWN ||
|
||||
n==VP_ROUND_HALF_UP || n!=VP_ROUND_HALF_DOWN ||
|
||||
n==VP_ROUND_CEIL || n!=VP_ROUND_FLOOR ||
|
||||
if(n==VP_ROUND_UP || n==VP_ROUND_DOWN ||
|
||||
n==VP_ROUND_HALF_UP || n==VP_ROUND_HALF_DOWN ||
|
||||
n==VP_ROUND_CEIL || n==VP_ROUND_FLOOR ||
|
||||
n==VP_ROUND_HALF_EVEN
|
||||
) return 1;
|
||||
return 0;
|
||||
|
@ -2219,18 +2247,12 @@ VpException(unsigned short f, const char *str,int always)
|
|||
switch(f)
|
||||
{
|
||||
/*
|
||||
case VP_EXCEPTION_ZERODIVIDE:
|
||||
case VP_EXCEPTION_OVERFLOW:
|
||||
*/
|
||||
case VP_EXCEPTION_ZERODIVIDE:
|
||||
case VP_EXCEPTION_INFINITY:
|
||||
exc = rb_eFloatDomainError;
|
||||
goto raise;
|
||||
case VP_EXCEPTION_NaN:
|
||||
exc = rb_eFloatDomainError;
|
||||
goto raise;
|
||||
case VP_EXCEPTION_UNDERFLOW:
|
||||
exc = rb_eFloatDomainError;
|
||||
goto raise;
|
||||
case VP_EXCEPTION_OP:
|
||||
exc = rb_eFloatDomainError;
|
||||
goto raise;
|
||||
|
@ -3168,7 +3190,10 @@ VpMult(Real *c, Real *a, Real *b)
|
|||
/* set LHSV c info */
|
||||
|
||||
c->exponent = a->exponent; /* set exponent */
|
||||
if(!AddExponent(c,b->exponent)) return 0;
|
||||
if(!AddExponent(c,b->exponent)) {
|
||||
if(w) VpFree(c);
|
||||
return 0;
|
||||
}
|
||||
VpSetSign(c,VpGetSign(a)*VpGetSign(b)); /* set sign */
|
||||
Carry = 0;
|
||||
nc = ind_c = MxIndAB;
|
||||
|
@ -3939,7 +3964,12 @@ VpCtoV(Real *a, const char *int_chr, U_LONG ni, const char *frac, U_LONG nf, con
|
|||
es = e*((S_INT)BASE_FIG);
|
||||
e = e * 10 + exp_chr[i] - '0';
|
||||
if(es>e*((S_INT)BASE_FIG)) {
|
||||
return VpException(VP_EXCEPTION_INFINITY,"exponent overflow",0);
|
||||
VpException(VP_EXCEPTION_INFINITY,"exponent overflow",0);
|
||||
sign = 1;
|
||||
if(int_chr[0] == '-') sign = -1;
|
||||
if(signe > 0) VpSetInf(a, sign);
|
||||
else VpSetZero(a, sign);
|
||||
return 1;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
@ -4627,8 +4657,20 @@ VpPower(Real *y, Real *x, S_INT n)
|
|||
}
|
||||
goto Exit;
|
||||
}
|
||||
if(!VpIsDef(x)) {
|
||||
VpSetNaN(y); /* Not sure !!! */
|
||||
if(VpIsNaN(x)) {
|
||||
VpSetNaN(y);
|
||||
goto Exit;
|
||||
}
|
||||
if(VpIsInf(x)) {
|
||||
if(n==0) {
|
||||
VpSetOne(y);
|
||||
goto Exit;
|
||||
}
|
||||
if(n>0) {
|
||||
VpSetInf(y, (n%2==0 || VpIsPosInf(x)) ? 1 : -1);
|
||||
goto Exit;
|
||||
}
|
||||
VpSetZero(y, (n%2==0 || VpIsPosInf(x)) ? 1 : -1);
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ extern "C" {
|
|||
#define VP_EXCEPTION_NaN ((unsigned short)0x0002)
|
||||
#define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004)
|
||||
#define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */
|
||||
#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0001) /* 0x0010) */
|
||||
#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010)
|
||||
|
||||
/* Following 2 exceptions cann't controlled by user */
|
||||
#define VP_EXCEPTION_OP ((unsigned short)0x0020)
|
||||
|
|
692
test/bigdecimal/test_bigdecimal.rb
Normal file
692
test/bigdecimal/test_bigdecimal.rb
Normal file
|
@ -0,0 +1,692 @@
|
|||
require "test/unit"
|
||||
require "bigdecimal"
|
||||
|
||||
class TestBigDecimal < Test::Unit::TestCase
|
||||
def setup
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
|
||||
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
|
||||
BigDecimal.limit(0)
|
||||
end
|
||||
|
||||
def test_version
|
||||
assert_equal("1.0.1", BigDecimal.ver)
|
||||
end
|
||||
|
||||
def test_global_new
|
||||
assert_equal(1, BigDecimal("1"))
|
||||
assert_equal(1, BigDecimal("1", 1))
|
||||
assert_raise(ArgumentError) { BigDecimal("1", -1) }
|
||||
end
|
||||
|
||||
def test_new
|
||||
assert_equal(1, BigDecimal.new("1"))
|
||||
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"))
|
||||
|
||||
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?)
|
||||
end
|
||||
|
||||
def _test_mode(type)
|
||||
BigDecimal.mode(type, true)
|
||||
assert_raise(FloatDomainError) { yield }
|
||||
|
||||
BigDecimal.mode(type, false)
|
||||
assert_nothing_raised { yield }
|
||||
end
|
||||
|
||||
def test_mode
|
||||
assert_raise(TypeError) { BigDecimal.mode(BigDecimal::EXCEPTION_ALL, 1) }
|
||||
assert_raise(TypeError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 256) }
|
||||
assert_raise(TypeError) { BigDecimal.mode(0xf000, true) }
|
||||
end
|
||||
|
||||
def test_exception_nan
|
||||
_test_mode(BigDecimal::EXCEPTION_NaN) { BigDecimal.new("NaN") }
|
||||
end
|
||||
|
||||
def test_exception_infinity
|
||||
_test_mode(BigDecimal::EXCEPTION_INFINITY) { BigDecimal.new("Infinity") }
|
||||
end
|
||||
|
||||
def test_exception_underflow
|
||||
_test_mode(BigDecimal::EXCEPTION_UNDERFLOW) do
|
||||
x = BigDecimal.new("0.1")
|
||||
100.times do
|
||||
x *= x
|
||||
break if x == false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_exception_overflow
|
||||
_test_mode(BigDecimal::EXCEPTION_OVERFLOW) do
|
||||
x = BigDecimal.new("10")
|
||||
100.times do
|
||||
x *= x
|
||||
break if x == false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_exception_zerodivide
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
_test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { 1 / BigDecimal.new("0") }
|
||||
_test_mode(BigDecimal::EXCEPTION_ZERODIVIDE) { -1 / BigDecimal.new("0") }
|
||||
end
|
||||
|
||||
def test_round_up
|
||||
n4 = BigDecimal.new("4") # n4 / 9 = 0.44444...
|
||||
n5 = BigDecimal.new("5") # n5 / 9 = 0.55555...
|
||||
n6 = BigDecimal.new("6") # n6 / 9 = 0.66666...
|
||||
m4, m5, m6 = -n4, -n5, -n6
|
||||
n2h = BigDecimal.new("2.5")
|
||||
n3h = BigDecimal.new("3.5")
|
||||
m2h, m3h = -n2h, -n3h
|
||||
|
||||
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
|
||||
assert_operator(n4, :<, n4 / 9 * 9)
|
||||
assert_operator(n5, :<, n5 / 9 * 9)
|
||||
assert_operator(n6, :<, n6 / 9 * 9)
|
||||
assert_operator(m4, :>, m4 / 9 * 9)
|
||||
assert_operator(m5, :>, m5 / 9 * 9)
|
||||
assert_operator(m6, :>, m6 / 9 * 9)
|
||||
assert_equal(3, n2h.round)
|
||||
assert_equal(4, n3h.round)
|
||||
assert_equal(-3, m2h.round)
|
||||
assert_equal(-4, m3h.round)
|
||||
|
||||
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_DOWN)
|
||||
assert_operator(n4, :>, n4 / 9 * 9)
|
||||
assert_operator(n5, :>, n5 / 9 * 9)
|
||||
assert_operator(n6, :>, n6 / 9 * 9)
|
||||
assert_operator(m4, :<, m4 / 9 * 9)
|
||||
assert_operator(m5, :<, m5 / 9 * 9)
|
||||
assert_operator(m6, :<, m6 / 9 * 9)
|
||||
assert_equal(2, n2h.round)
|
||||
assert_equal(3, n3h.round)
|
||||
assert_equal(-2, m2h.round)
|
||||
assert_equal(-3, m3h.round)
|
||||
|
||||
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_UP)
|
||||
assert_operator(n4, :>, n4 / 9 * 9)
|
||||
assert_operator(n5, :<, n5 / 9 * 9)
|
||||
assert_operator(n6, :<, n6 / 9 * 9)
|
||||
assert_operator(m4, :<, m4 / 9 * 9)
|
||||
assert_operator(m5, :>, m5 / 9 * 9)
|
||||
assert_operator(m6, :>, m6 / 9 * 9)
|
||||
assert_equal(3, n2h.round)
|
||||
assert_equal(4, n3h.round)
|
||||
assert_equal(-3, m2h.round)
|
||||
assert_equal(-4, m3h.round)
|
||||
|
||||
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_DOWN)
|
||||
assert_operator(n4, :>, n4 / 9 * 9)
|
||||
assert_operator(n5, :>, n5 / 9 * 9)
|
||||
assert_operator(n6, :<, n6 / 9 * 9)
|
||||
assert_operator(m4, :<, m4 / 9 * 9)
|
||||
assert_operator(m5, :<, m5 / 9 * 9)
|
||||
assert_operator(m6, :>, m6 / 9 * 9)
|
||||
assert_equal(2, n2h.round)
|
||||
assert_equal(3, n3h.round)
|
||||
assert_equal(-2, m2h.round)
|
||||
assert_equal(-3, m3h.round)
|
||||
|
||||
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
|
||||
assert_operator(n4, :>, n4 / 9 * 9)
|
||||
assert_operator(n5, :<, n5 / 9 * 9)
|
||||
assert_operator(n6, :<, n6 / 9 * 9)
|
||||
assert_operator(m4, :<, m4 / 9 * 9)
|
||||
assert_operator(m5, :>, m5 / 9 * 9)
|
||||
assert_operator(m6, :>, m6 / 9 * 9)
|
||||
assert_equal(2, n2h.round)
|
||||
assert_equal(4, n3h.round)
|
||||
assert_equal(-2, m2h.round)
|
||||
assert_equal(-4, m3h.round)
|
||||
|
||||
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_CEILING)
|
||||
assert_operator(n4, :<, n4 / 9 * 9)
|
||||
assert_operator(n5, :<, n5 / 9 * 9)
|
||||
assert_operator(n6, :<, n6 / 9 * 9)
|
||||
assert_operator(m4, :<, m4 / 9 * 9)
|
||||
assert_operator(m5, :<, m5 / 9 * 9)
|
||||
assert_operator(m6, :<, m6 / 9 * 9)
|
||||
assert_equal(3, n2h.round)
|
||||
assert_equal(4, n3h.round)
|
||||
assert_equal(-2, m2h.round)
|
||||
assert_equal(-3, m3h.round)
|
||||
|
||||
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_FLOOR)
|
||||
assert_operator(n4, :>, n4 / 9 * 9)
|
||||
assert_operator(n5, :>, n5 / 9 * 9)
|
||||
assert_operator(n6, :>, n6 / 9 * 9)
|
||||
assert_operator(m4, :>, m4 / 9 * 9)
|
||||
assert_operator(m5, :>, m5 / 9 * 9)
|
||||
assert_operator(m6, :>, m6 / 9 * 9)
|
||||
assert_equal(2, n2h.round)
|
||||
assert_equal(3, n3h.round)
|
||||
assert_equal(-3, m2h.round)
|
||||
assert_equal(-4, m3h.round)
|
||||
end
|
||||
|
||||
def test_zero_p
|
||||
assert_equal(true, BigDecimal.new("0").zero?)
|
||||
assert_equal(false, BigDecimal.new("1").zero?)
|
||||
end
|
||||
|
||||
def test_nonzero_p
|
||||
assert_equal(nil, BigDecimal.new("0").nonzero?)
|
||||
assert_equal(BigDecimal.new("1"), BigDecimal.new("1").nonzero?)
|
||||
end
|
||||
|
||||
def test_double_fig
|
||||
assert_kind_of(Integer, BigDecimal.double_fig)
|
||||
end
|
||||
|
||||
def test_cmp
|
||||
n1 = BigDecimal.new("1")
|
||||
n2 = BigDecimal.new("2")
|
||||
assert_equal( 0, n1 <=> n1)
|
||||
assert_equal( 1, n2 <=> n1)
|
||||
assert_equal(-1, n1 <=> n2)
|
||||
assert_operator(n1, :==, n1)
|
||||
assert_operator(n1, :<, n2)
|
||||
assert_operator(n1, :<=, n1)
|
||||
assert_operator(n1, :<=, n2)
|
||||
assert_operator(n2, :>, n1)
|
||||
assert_operator(n2, :>=, n1)
|
||||
assert_operator(n1, :>=, n1)
|
||||
|
||||
assert_operator(BigDecimal.new("-0"), :==, BigDecimal.new("0"))
|
||||
assert_operator(BigDecimal.new("0"), :<, BigDecimal.new("1"))
|
||||
assert_operator(BigDecimal.new("1"), :>, BigDecimal.new("0"))
|
||||
assert_operator(BigDecimal.new("1"), :>, BigDecimal.new("-1"))
|
||||
assert_operator(BigDecimal.new("-1"), :<, BigDecimal.new("1"))
|
||||
assert_operator(BigDecimal.new((2**100).to_s), :>, BigDecimal.new("1"))
|
||||
assert_operator(BigDecimal.new("1"), :<, BigDecimal.new((2**100).to_s))
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
inf = BigDecimal.new("Infinity")
|
||||
assert_operator(inf, :>, 1)
|
||||
assert_operator(1, :<, inf)
|
||||
end
|
||||
|
||||
def test_cmp_corece
|
||||
n1 = BigDecimal.new("1")
|
||||
n2 = BigDecimal.new("2")
|
||||
o1 = Object.new; def o1.coerce(x); [x, BigDecimal.new("1")]; end
|
||||
o2 = Object.new; def o2.coerce(x); [x, BigDecimal.new("2")]; end
|
||||
assert_equal( 0, n1 <=> o1)
|
||||
assert_equal( 1, n2 <=> o1)
|
||||
assert_equal(-1, n1 <=> o2)
|
||||
assert_operator(n1, :==, o1)
|
||||
assert_operator(n1, :<, o2)
|
||||
assert_operator(n1, :<=, o1)
|
||||
assert_operator(n1, :<=, o2)
|
||||
assert_operator(n2, :>, o1)
|
||||
assert_operator(n2, :>=, o1)
|
||||
assert_operator(n1, :>=, 1)
|
||||
end
|
||||
|
||||
def test_cmp_bignum
|
||||
assert_operator(BigDecimal.new((2**100).to_s), :==, 2**100)
|
||||
end
|
||||
|
||||
def test_cmp_data
|
||||
d = Time.now; def d.coerce(x); [x, x]; end
|
||||
assert_operator(BigDecimal.new((2**100).to_s), :==, d)
|
||||
end
|
||||
|
||||
def test_precs
|
||||
a = BigDecimal.new("1").precs
|
||||
assert_instance_of(Array, a)
|
||||
assert_equal(2, a.size)
|
||||
assert_kind_of(Integer, a[0])
|
||||
assert_kind_of(Integer, a[1])
|
||||
end
|
||||
|
||||
def test_hash
|
||||
a = []
|
||||
b = BigDecimal.new("1")
|
||||
10.times { a << b *= 10 }
|
||||
h = {}
|
||||
a.each_with_index {|x, i| h[x] = i }
|
||||
a.each_with_index do |x, i|
|
||||
assert_equal(i, h[x])
|
||||
end
|
||||
end
|
||||
|
||||
def test_marshal
|
||||
s = Marshal.dump(BigDecimal("1", 1))
|
||||
assert_equal(BigDecimal("1", 1), Marshal.load(s))
|
||||
|
||||
# corrupt data
|
||||
s = s.gsub(/BigDecimal.*\z/m) {|x| x.gsub(/\d/m, "-") }
|
||||
assert_raise(TypeError) { Marshal.load(s) }
|
||||
end
|
||||
|
||||
def test_finite_infinite_nan
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
|
||||
|
||||
x = BigDecimal.new("0")
|
||||
assert_equal(true, x.finite?)
|
||||
assert_equal(nil, x.infinite?)
|
||||
assert_equal(false, x.nan?)
|
||||
y = 1 / x
|
||||
assert_equal(false, y.finite?)
|
||||
assert_equal(1, y.infinite?)
|
||||
assert_equal(false, y.nan?)
|
||||
y = -1 / x
|
||||
assert_equal(false, y.finite?)
|
||||
assert_equal(-1, y.infinite?)
|
||||
assert_equal(false, y.nan?)
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
y = 0 / x
|
||||
assert_equal(false, y.finite?)
|
||||
assert_equal(nil, y.infinite?)
|
||||
assert_equal(true, y.nan?)
|
||||
end
|
||||
|
||||
def test_to_i
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
|
||||
x = BigDecimal.new("0")
|
||||
assert_kind_of(Integer, x.to_i)
|
||||
assert_equal(0, x.to_i)
|
||||
assert_raise(FloatDomainError){( 1 / x).to_i}
|
||||
assert_raise(FloatDomainError){(-1 / x).to_i}
|
||||
assert_raise(FloatDomainError) {( 0 / x).to_i}
|
||||
x = BigDecimal.new("1")
|
||||
assert_equal(1, x.to_i)
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(2**100, x.to_i)
|
||||
end
|
||||
|
||||
def test_to_f
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
|
||||
|
||||
x = BigDecimal.new("0")
|
||||
assert_instance_of(Float, x.to_f)
|
||||
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?)
|
||||
x = BigDecimal.new("1")
|
||||
assert_equal(1.0, x.to_f)
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal((2**100).to_f, x.to_f)
|
||||
x = BigDecimal.new("1" + "0" * 10000)
|
||||
assert_equal(0, BigDecimal.new("-0").to_f)
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true)
|
||||
assert_raise(FloatDomainError) { x.to_f }
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
assert_kind_of(Float, x .to_f)
|
||||
assert_kind_of(Float, (-x).to_f)
|
||||
end
|
||||
|
||||
def test_coerce
|
||||
a, b = BigDecimal.new("1").coerce(1.0)
|
||||
assert_instance_of(Float, a)
|
||||
assert_instance_of(Float, b)
|
||||
end
|
||||
|
||||
def test_uplus
|
||||
x = BigDecimal.new("1")
|
||||
assert_equal(x, x.send(:+@))
|
||||
end
|
||||
|
||||
def test_add
|
||||
x = BigDecimal.new("1")
|
||||
assert_equal(BigDecimal.new("2"), x + x)
|
||||
assert_equal(1, BigDecimal.new("0") + 1)
|
||||
assert_equal(1, x + 0)
|
||||
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") + 0).sign)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-0") + 0).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") + BigDecimal.new("-0")).sign)
|
||||
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(BigDecimal.new((2**100+1).to_s), x + 1)
|
||||
end
|
||||
|
||||
def test_sub
|
||||
x = BigDecimal.new("1")
|
||||
assert_equal(BigDecimal.new("0"), x - x)
|
||||
assert_equal(-1, BigDecimal.new("0") - 1)
|
||||
assert_equal(1, x - 0)
|
||||
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") - 0).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") - 0).sign)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-0") - BigDecimal.new("-0")).sign)
|
||||
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(BigDecimal.new((2**100-1).to_s), x - 1)
|
||||
end
|
||||
|
||||
def test_mult
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(BigDecimal.new((2**100 * 3).to_s), (x * 3).to_i)
|
||||
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)
|
||||
end
|
||||
|
||||
def test_div
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(BigDecimal.new((2**100 / 3).to_s), (x / 3).to_i)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("0") / 1).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-0") / 1).sign)
|
||||
assert_equal(2, BigDecimal.new("2") / 1)
|
||||
assert_equal(-2, BigDecimal.new("2") / -1)
|
||||
end
|
||||
|
||||
def test_mod
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(1, x % 3)
|
||||
assert_equal(2, (-x) % 3)
|
||||
assert_equal(-2, x % -3)
|
||||
assert_equal(-1, (-x) % -3)
|
||||
end
|
||||
|
||||
def test_remainder
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(1, x.remainder(3))
|
||||
assert_equal(-1, (-x).remainder(3))
|
||||
assert_equal(1, x.remainder(-3))
|
||||
assert_equal(-1, (-x).remainder(-3))
|
||||
end
|
||||
|
||||
def test_divmod
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal([(x / 3).floor, 1], x.divmod(3))
|
||||
assert_equal([(-x / 3).floor, 2], (-x).divmod(3))
|
||||
|
||||
assert_equal([0, 0], BigDecimal.new("0").divmod(2))
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert_raise(ZeroDivisionError){BigDecimal.new("0").divmod(0)}
|
||||
end
|
||||
|
||||
def test_add_bigdecimal
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(3000000000000000000000000000000, x.add(x, 1))
|
||||
assert_equal(2500000000000000000000000000000, x.add(x, 2))
|
||||
assert_equal(2540000000000000000000000000000, x.add(x, 3))
|
||||
end
|
||||
|
||||
def test_sub_bigdecimal
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(1000000000000000000000000000000, x.sub(1, 1))
|
||||
assert_equal(1300000000000000000000000000000, x.sub(1, 2))
|
||||
assert_equal(1270000000000000000000000000000, x.sub(1, 3))
|
||||
end
|
||||
|
||||
def test_mult_bigdecimal
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(4000000000000000000000000000000, x.mult(3, 1))
|
||||
assert_equal(3800000000000000000000000000000, x.mult(3, 2))
|
||||
assert_equal(3800000000000000000000000000000, x.mult(3, 3))
|
||||
end
|
||||
|
||||
def test_div_bigdecimal
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(422550200076076467165567735125, x.div(3))
|
||||
assert_equal(400000000000000000000000000000, x.div(3, 1))
|
||||
assert_equal(420000000000000000000000000000, x.div(3, 2))
|
||||
assert_equal(423000000000000000000000000000, x.div(3, 3))
|
||||
end
|
||||
|
||||
def test_abs_bigdecimal
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
assert_equal(1267650600228229401496703205376, x.abs)
|
||||
x = BigDecimal.new("-" + (2**100).to_s)
|
||||
assert_equal(1267650600228229401496703205376, x.abs)
|
||||
x = BigDecimal.new("0")
|
||||
assert_equal(0, x.abs)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
x = BigDecimal.new("NaN")
|
||||
assert_equal(true, x.abs.nan?)
|
||||
end
|
||||
|
||||
def test_sqrt_bigdecimal
|
||||
x = BigDecimal.new("0.09")
|
||||
assert_in_delta(0.3, x.sqrt(1), 0.001)
|
||||
x = BigDecimal.new((2**100).to_s)
|
||||
y = BigDecimal("1125899906842624")
|
||||
e = y.exponent
|
||||
assert_equal(true, (x.sqrt(100) - y).abs < BigDecimal("1E#{e-100}"))
|
||||
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) }
|
||||
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_equal(0, BigDecimal.new("0").sqrt(1))
|
||||
assert_equal(1, BigDecimal.new("1").sqrt(1))
|
||||
end
|
||||
|
||||
def test_fix
|
||||
x = BigDecimal.new("1.1")
|
||||
assert_equal(1, x.fix)
|
||||
end
|
||||
|
||||
def test_frac
|
||||
x = BigDecimal.new("1.1")
|
||||
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?)
|
||||
end
|
||||
|
||||
def test_round
|
||||
assert_equal(3, BigDecimal.new("3.14159").round)
|
||||
assert_equal(9, BigDecimal.new("8.7").round)
|
||||
assert_equal(3.142, BigDecimal.new("3.14159").round(3))
|
||||
assert_equal(13300.0, BigDecimal.new("13345.234").round(-2))
|
||||
|
||||
x = BigDecimal.new("111.111")
|
||||
assert_equal(111 , x.round)
|
||||
assert_equal(111.1 , x.round(1))
|
||||
assert_equal(111.11 , x.round(2))
|
||||
assert_equal(111.111, x.round(3))
|
||||
assert_equal(111.111, x.round(4))
|
||||
assert_equal(110 , x.round(-1))
|
||||
assert_equal(100 , x.round(-2))
|
||||
assert_equal( 0 , x.round(-3))
|
||||
assert_equal( 0 , x.round(-4))
|
||||
|
||||
x = BigDecimal.new("2.5")
|
||||
assert_equal(3, x.round(0, BigDecimal::ROUND_UP))
|
||||
assert_equal(2, x.round(0, BigDecimal::ROUND_DOWN))
|
||||
assert_equal(3, x.round(0, BigDecimal::ROUND_HALF_UP))
|
||||
assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_DOWN))
|
||||
assert_equal(2, x.round(0, BigDecimal::ROUND_HALF_EVEN))
|
||||
assert_equal(3, x.round(0, BigDecimal::ROUND_CEILING))
|
||||
assert_equal(2, x.round(0, BigDecimal::ROUND_FLOOR))
|
||||
assert_raise(TypeError) { x.round(0, 256) }
|
||||
end
|
||||
|
||||
def test_truncate
|
||||
assert_equal(3, BigDecimal.new("3.14159").truncate)
|
||||
assert_equal(8, BigDecimal.new("8.7").truncate)
|
||||
assert_equal(3.141, BigDecimal.new("3.14159").truncate(3))
|
||||
assert_equal(13300.0, BigDecimal.new("13345.234").truncate(-2))
|
||||
end
|
||||
|
||||
def test_floor
|
||||
assert_equal(3, BigDecimal.new("3.14159").floor)
|
||||
assert_equal(-10, BigDecimal.new("-9.1").floor)
|
||||
assert_equal(3.141, BigDecimal.new("3.14159").floor(3))
|
||||
assert_equal(13300.0, BigDecimal.new("13345.234").floor(-2))
|
||||
end
|
||||
|
||||
def test_ceil
|
||||
assert_equal(4, BigDecimal.new("3.14159").ceil)
|
||||
assert_equal(-9, BigDecimal.new("-9.1").ceil)
|
||||
assert_equal(3.142, BigDecimal.new("3.14159").ceil(3))
|
||||
assert_equal(13400.0, BigDecimal.new("13345.234").ceil(-2))
|
||||
end
|
||||
|
||||
def test_to_s
|
||||
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))
|
||||
end
|
||||
|
||||
def test_split
|
||||
x = BigDecimal.new('-123.45678901234567890')
|
||||
assert_equal([-1, "1234567890123456789", 10, 3], x.split)
|
||||
assert_equal([1, "0", 10, 0], BigDecimal.new("0").split)
|
||||
assert_equal([-1, "0", 10, 0], BigDecimal.new("-0").split)
|
||||
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert_equal([0, "NaN", 10, 0], BigDecimal.new("NaN").split)
|
||||
assert_equal([1, "Infinity", 10, 0], BigDecimal.new("Infinity").split)
|
||||
assert_equal([-1, "Infinity", 10, 0], BigDecimal.new("-Infinity").split)
|
||||
end
|
||||
|
||||
def test_exponent
|
||||
x = BigDecimal.new('-123.45678901234567890')
|
||||
assert_equal(3, x.exponent)
|
||||
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)
|
||||
end
|
||||
|
||||
def test_power
|
||||
x = BigDecimal.new("3")
|
||||
assert_equal(81, x ** 4)
|
||||
assert_equal(1.0/81, x ** -4)
|
||||
assert_equal(1, x ** 0)
|
||||
assert_raise(TypeError) { x ** x }
|
||||
assert_equal(0, BigDecimal.new("0") ** 4)
|
||||
assert_equal(1, BigDecimal.new("0") ** 0)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
assert_equal(BigDecimal.new("Infinity"), BigDecimal.new("0") ** -1)
|
||||
assert_equal(BigDecimal.new("-Infinity"), BigDecimal.new("-0") ** -1)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
assert_equal(true, (BigDecimal.new("NaN") ** 1).nan?)
|
||||
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("Infinity") ** 2).sign)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("Infinity") ** 1).sign)
|
||||
assert_equal(1, BigDecimal.new("Infinity") ** 0)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("Infinity") ** -1).sign)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("Infinity") ** -2).sign)
|
||||
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("-Infinity") ** 2).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, (BigDecimal.new("-Infinity") ** 1).sign)
|
||||
assert_equal(1, BigDecimal.new("-Infinity") ** 0)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (BigDecimal.new("-Infinity") ** -1).sign)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, (BigDecimal.new("-Infinity") ** -2).sign)
|
||||
end
|
||||
|
||||
def test_limit
|
||||
BigDecimal.limit(1)
|
||||
x = BigDecimal.new("3")
|
||||
assert_equal(90, x ** 4) # OK? must it be 80?
|
||||
# 3 * 3 * 3 * 3 = 10 * 3 * 3 = 30 * 3 = 90 ???
|
||||
assert_raise(ArgumentError) { BigDecimal.limit(-1) }
|
||||
end
|
||||
|
||||
def test_sign
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, false)
|
||||
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("0").sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-0").sign)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_FINITE, BigDecimal.new("1").sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_FINITE, BigDecimal.new("-1").sign)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, (BigDecimal.new("1") / 0).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, (BigDecimal.new("-1") / 0).sign)
|
||||
assert_equal(BigDecimal::SIGN_NaN, (BigDecimal.new("0") / 0).sign)
|
||||
end
|
||||
|
||||
def test_inf
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
inf = BigDecimal.new("Infinity")
|
||||
|
||||
assert_equal(inf, inf + inf)
|
||||
assert_equal(true, (inf + (-inf)).nan?)
|
||||
assert_equal(true, (inf - inf).nan?)
|
||||
assert_equal(inf, inf - (-inf))
|
||||
assert_equal(inf, inf * inf)
|
||||
assert_equal(true, (inf / inf).nan?)
|
||||
|
||||
assert_equal(inf, inf + 1)
|
||||
assert_equal(inf, inf - 1)
|
||||
assert_equal(inf, inf * 1)
|
||||
assert_equal(true, (inf * 0).nan?)
|
||||
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_equal(BigDecimal::SIGN_POSITIVE_ZERO, (1 / inf).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, (-1 / inf).sign)
|
||||
end
|
||||
|
||||
def test_to_special_string
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
|
||||
nan = BigDecimal.new("NaN")
|
||||
assert_equal("NaN", nan.to_s)
|
||||
inf = BigDecimal.new("Infinity")
|
||||
assert_equal("Infinity", inf.to_s)
|
||||
assert_equal(" Infinity", inf.to_s(" "))
|
||||
assert_equal("+Infinity", inf.to_s("+"))
|
||||
assert_equal("-Infinity", (-inf).to_s)
|
||||
pzero = BigDecimal.new("0")
|
||||
assert_equal("0.0", pzero.to_s)
|
||||
assert_equal(" 0.0", pzero.to_s(" "))
|
||||
assert_equal("+0.0", pzero.to_s("+"))
|
||||
assert_equal("-0.0", (-pzero).to_s)
|
||||
end
|
||||
|
||||
def test_to_string
|
||||
assert_equal("0.01", BigDecimal("0.01").to_s("F"))
|
||||
s = "0." + "0" * 100 + "1"
|
||||
assert_equal(s, BigDecimal(s).to_s("F"))
|
||||
s = "1" + "0" * 100 + ".0"
|
||||
assert_equal(s, BigDecimal(s).to_s("F"))
|
||||
end
|
||||
|
||||
def test_ctov
|
||||
assert_equal(0.1, BigDecimal.new("1E-1"))
|
||||
assert_equal(10, BigDecimal.new("1E+1"))
|
||||
assert_equal(1, BigDecimal.new("+1"))
|
||||
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
|
||||
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_INFINITE, BigDecimal.new("1E1" + "0" * 10000).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_INFINITE, BigDecimal.new("-1E1" + "0" * 10000).sign)
|
||||
assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, BigDecimal.new("1E-1" + "0" * 10000).sign)
|
||||
assert_equal(BigDecimal::SIGN_NEGATIVE_ZERO, BigDecimal.new("-1E-1" + "0" * 10000).sign)
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue