* ext/bigdecimal/bigdecimal.c (Init_bigdecimal, rmpd_set_thread_local_exception_mode, VpGetException, VpSetException): thread-local exception mode.
* ext/bigdecimal/bigdecimal.c (Init_bigdecimal, rmpd_set_thread_local_precision_limit, VpGetPrecLimit, VpSetPrecLimit): thread-local precision limit. * ext/bigdecimal/bigdecimal.c (Init_bigdecimal, rmpd_set_thread_local_rounding_mode, VpGetRoundMode, VpSetRoundMode, VpException, VpInternalRound): thread-local rounding mode. * ext/bigdecimal/bigdecimal.c (BigDecimal_mode, BigDecimal_round, VpIsRoundMode, VpGetRoundMode, VpSetRoundMode, VpActiveRound, VpMidRound, VpLeftRound), ext/bigdecimal/bigdecimal.h: use unsigned short for rounding mode. * test/bigdecimal/test_bigdecimal.rb (test_mode): add test for setting rounding mode. * test/bigdecimal/test_bigdecimal.rb (test_thread_local_mode): add test for setting mode thread-locally. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29099 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
8554e16355
commit
3dc6edf793
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
|||||||
|
Tue Aug 26 09:11:40 2010 Kenta Murata <mrkn@mrkn.jp>
|
||||||
|
|
||||||
|
* ext/bigdecimal/bigdecimal.c (Init_bigdecimal,
|
||||||
|
rmpd_set_thread_local_exception_mode, VpGetException,
|
||||||
|
VpSetException): thread-local exception mode.
|
||||||
|
|
||||||
|
* ext/bigdecimal/bigdecimal.c (Init_bigdecimal,
|
||||||
|
rmpd_set_thread_local_precision_limit, VpGetPrecLimit,
|
||||||
|
VpSetPrecLimit): thread-local precision limit.
|
||||||
|
|
||||||
|
* ext/bigdecimal/bigdecimal.c (Init_bigdecimal,
|
||||||
|
rmpd_set_thread_local_rounding_mode, VpGetRoundMode,
|
||||||
|
VpSetRoundMode, VpException, VpInternalRound):
|
||||||
|
thread-local rounding mode.
|
||||||
|
|
||||||
|
* ext/bigdecimal/bigdecimal.c (BigDecimal_mode, BigDecimal_round,
|
||||||
|
VpIsRoundMode, VpGetRoundMode, VpSetRoundMode, VpActiveRound,
|
||||||
|
VpMidRound, VpLeftRound), ext/bigdecimal/bigdecimal.h:
|
||||||
|
use unsigned short for rounding mode.
|
||||||
|
|
||||||
|
* test/bigdecimal/test_bigdecimal.rb (test_mode): add test for
|
||||||
|
setting rounding mode.
|
||||||
|
|
||||||
|
* test/bigdecimal/test_bigdecimal.rb (test_thread_local_mode):
|
||||||
|
add test for setting mode thread-locally.
|
||||||
|
|
||||||
Thu Aug 26 07:29:54 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Aug 26 07:29:54 2010 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* array.c (rb_ary_{shuffle_bang,sample}): use Random class object.
|
* array.c (rb_ary_{shuffle_bang,sample}): use Random class object.
|
||||||
|
@ -32,6 +32,10 @@
|
|||||||
|
|
||||||
VALUE rb_cBigDecimal;
|
VALUE rb_cBigDecimal;
|
||||||
|
|
||||||
|
static ID id_BigDecimal_exception_mode;
|
||||||
|
static ID id_BigDecimal_rounding_mode;
|
||||||
|
static ID id_BigDecimal_precision_limit;
|
||||||
|
|
||||||
/* MACRO's to guard objects from GC by keeping them in stack */
|
/* MACRO's to guard objects from GC by keeping them in stack */
|
||||||
#define ENTER(n) volatile VALUE vStack[n];int iStack=0
|
#define ENTER(n) volatile VALUE vStack[n];int iStack=0
|
||||||
#define PUSH(x) vStack[iStack++] = (unsigned long)(x);
|
#define PUSH(x) vStack[iStack++] = (unsigned long)(x);
|
||||||
@ -358,11 +362,11 @@ BigDecimal_mode(int argc, VALUE *argv, VALUE self)
|
|||||||
fo = VpGetRoundMode();
|
fo = VpGetRoundMode();
|
||||||
if(val==Qnil) return INT2FIX(fo);
|
if(val==Qnil) return INT2FIX(fo);
|
||||||
Check_Type(val, T_FIXNUM);
|
Check_Type(val, T_FIXNUM);
|
||||||
if(!VpIsRoundMode(FIX2INT(val))) {
|
if(!VpIsRoundMode((unsigned short)FIX2INT(val))) {
|
||||||
rb_raise(rb_eTypeError, "invalid rounding mode");
|
rb_raise(rb_eTypeError, "invalid rounding mode");
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
fo = VpSetRoundMode((unsigned long)FIX2INT(val));
|
fo = VpSetRoundMode((unsigned short)FIX2INT(val));
|
||||||
return INT2FIX(fo);
|
return INT2FIX(fo);
|
||||||
}
|
}
|
||||||
rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid");
|
rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid");
|
||||||
@ -1279,7 +1283,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
|||||||
VALUE vRound;
|
VALUE vRound;
|
||||||
size_t mx, pl;
|
size_t mx, pl;
|
||||||
|
|
||||||
int sw = (int)VpGetRoundMode();
|
unsigned short sw = VpGetRoundMode();
|
||||||
|
|
||||||
int na = rb_scan_args(argc,argv,"02",&vLoc,&vRound);
|
int na = rb_scan_args(argc,argv,"02",&vLoc,&vRound);
|
||||||
switch(na) {
|
switch(na) {
|
||||||
@ -1294,7 +1298,7 @@ BigDecimal_round(int argc, VALUE *argv, VALUE self)
|
|||||||
Check_Type(vLoc, T_FIXNUM);
|
Check_Type(vLoc, T_FIXNUM);
|
||||||
iLoc = FIX2INT(vLoc);
|
iLoc = FIX2INT(vLoc);
|
||||||
Check_Type(vRound, T_FIXNUM);
|
Check_Type(vRound, T_FIXNUM);
|
||||||
sw = FIX2INT(vRound);
|
sw = (unsigned short)FIX2INT(vRound);
|
||||||
if(!VpIsRoundMode(sw)) {
|
if(!VpIsRoundMode(sw)) {
|
||||||
rb_raise(rb_eTypeError, "invalid rounding mode");
|
rb_raise(rb_eTypeError, "invalid rounding mode");
|
||||||
return Qnil;
|
return Qnil;
|
||||||
@ -2086,6 +2090,10 @@ Init_bigdecimal(void)
|
|||||||
rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0);
|
rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0);
|
||||||
rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1);
|
rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1);
|
||||||
rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1);
|
rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1);
|
||||||
|
|
||||||
|
id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode");
|
||||||
|
id_BigDecimal_rounding_mode = rb_intern_const("BigDecimal.rounding_mode");
|
||||||
|
id_BigDecimal_precision_limit = rb_intern_const("BigDecimal.precision_limit");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2104,9 +2112,6 @@ static int gfCheckVal = 1; /* Value checking flag in VpNmlz() */
|
|||||||
#endif
|
#endif
|
||||||
#endif /* BIGDECIMAL_DEBUG */
|
#endif /* BIGDECIMAL_DEBUG */
|
||||||
|
|
||||||
static size_t gnPrecLimit = 0; /* Global upper limit of the precision newly allocated */
|
|
||||||
static size_t gfRoundMode = VP_ROUND_HALF_UP; /* Mode for general rounding operation */
|
|
||||||
|
|
||||||
static Real *VpConstOne; /* constant 1.0 */
|
static Real *VpConstOne; /* constant 1.0 */
|
||||||
static Real *VpPt5; /* constant 0.5 */
|
static Real *VpPt5; /* constant 0.5 */
|
||||||
#define maxnr 100UL /* Maximum iterations for calcurating sqrt. */
|
#define maxnr 100UL /* Maximum iterations for calcurating sqrt. */
|
||||||
@ -2165,57 +2170,127 @@ VpFree(Real *pv)
|
|||||||
/*
|
/*
|
||||||
* EXCEPTION Handling.
|
* EXCEPTION Handling.
|
||||||
*/
|
*/
|
||||||
static unsigned short gfDoException = 0; /* Exception flag */
|
|
||||||
|
#define rmpd_set_thread_local_exception_mode(mode) \
|
||||||
|
rb_thread_local_aset( \
|
||||||
|
rb_thread_current(), \
|
||||||
|
id_BigDecimal_exception_mode, \
|
||||||
|
INT2FIX((int)(mode)) \
|
||||||
|
)
|
||||||
|
|
||||||
static unsigned short
|
static unsigned short
|
||||||
VpGetException (void)
|
VpGetException (void)
|
||||||
{
|
{
|
||||||
return gfDoException;
|
VALUE const vmode = rb_thread_local_aref(
|
||||||
|
rb_thread_current(),
|
||||||
|
id_BigDecimal_exception_mode
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NIL_P(vmode)) {
|
||||||
|
rmpd_set_thread_local_exception_mode(RMPD_EXCEPTION_MODE_DEFAULT);
|
||||||
|
return RMPD_EXCEPTION_MODE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned short)FIX2UINT(vmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
VpSetException(unsigned short f)
|
VpSetException(unsigned short f)
|
||||||
{
|
{
|
||||||
gfDoException = f;
|
rmpd_set_thread_local_exception_mode(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Precision limit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define rmpd_set_thread_local_precision_limit(limit) \
|
||||||
|
rb_thread_local_aset( \
|
||||||
|
rb_thread_current(), \
|
||||||
|
id_BigDecimal_precision_limit, \
|
||||||
|
SIZET2NUM(limit) \
|
||||||
|
)
|
||||||
|
#define RMPD_PRECISION_LIMIT_DEFAULT ((size_t)0)
|
||||||
|
|
||||||
/* These 2 functions added at v1.1.7 */
|
/* These 2 functions added at v1.1.7 */
|
||||||
VP_EXPORT size_t
|
VP_EXPORT size_t
|
||||||
VpGetPrecLimit(void)
|
VpGetPrecLimit(void)
|
||||||
{
|
{
|
||||||
return gnPrecLimit;
|
VALUE const vlimit = rb_thread_local_aref(
|
||||||
|
rb_thread_current(),
|
||||||
|
id_BigDecimal_precision_limit
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NIL_P(vlimit)) {
|
||||||
|
rmpd_set_thread_local_precision_limit(RMPD_PRECISION_LIMIT_DEFAULT);
|
||||||
|
return RMPD_PRECISION_LIMIT_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NUM2SIZET(vlimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT size_t
|
VP_EXPORT size_t
|
||||||
VpSetPrecLimit(size_t n)
|
VpSetPrecLimit(size_t n)
|
||||||
{
|
{
|
||||||
size_t s = gnPrecLimit;
|
size_t const s = VpGetPrecLimit();
|
||||||
gnPrecLimit = n;
|
rmpd_set_thread_local_precision_limit(n);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT unsigned long
|
/*
|
||||||
|
* Rounding mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define rmpd_set_thread_local_rounding_mode(mode) \
|
||||||
|
rb_thread_local_aset( \
|
||||||
|
rb_thread_current(), \
|
||||||
|
id_BigDecimal_rounding_mode, \
|
||||||
|
INT2FIX((int)(mode)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
VP_EXPORT unsigned short
|
||||||
VpGetRoundMode(void)
|
VpGetRoundMode(void)
|
||||||
{
|
{
|
||||||
return gfRoundMode;
|
VALUE const vmode = rb_thread_local_aref(
|
||||||
|
rb_thread_current(),
|
||||||
|
id_BigDecimal_rounding_mode
|
||||||
|
);
|
||||||
|
|
||||||
|
if (NIL_P(vmode)) {
|
||||||
|
rmpd_set_thread_local_rounding_mode(RMPD_ROUNDING_MODE_DEFAULT);
|
||||||
|
return RMPD_ROUNDING_MODE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned short)FIX2INT(vmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT int
|
VP_EXPORT int
|
||||||
VpIsRoundMode(unsigned long n)
|
VpIsRoundMode(unsigned short n)
|
||||||
{
|
{
|
||||||
if(n==VP_ROUND_UP || n==VP_ROUND_DOWN ||
|
switch (n) {
|
||||||
n==VP_ROUND_HALF_UP || n==VP_ROUND_HALF_DOWN ||
|
case VP_ROUND_UP:
|
||||||
n==VP_ROUND_CEIL || n==VP_ROUND_FLOOR ||
|
case VP_ROUND_DOWN:
|
||||||
n==VP_ROUND_HALF_EVEN
|
case VP_ROUND_HALF_UP:
|
||||||
) return 1;
|
case VP_ROUND_HALF_DOWN:
|
||||||
return 0;
|
case VP_ROUND_CEIL:
|
||||||
|
case VP_ROUND_FLOOR:
|
||||||
|
case VP_ROUND_HALF_EVEN:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT unsigned long
|
VP_EXPORT unsigned short
|
||||||
VpSetRoundMode(unsigned long n)
|
VpSetRoundMode(unsigned short n)
|
||||||
{
|
{
|
||||||
if(VpIsRoundMode(n)) gfRoundMode = n;
|
if (VpIsRoundMode(n)) {
|
||||||
return gfRoundMode;
|
rmpd_set_thread_local_rounding_mode(n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return VpGetRoundMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2300,10 +2375,11 @@ VpException(unsigned short f, const char *str,int always)
|
|||||||
{
|
{
|
||||||
VALUE exc;
|
VALUE exc;
|
||||||
int fatal=0;
|
int fatal=0;
|
||||||
|
unsigned short const exception_mode = VpGetException();
|
||||||
|
|
||||||
if(f==VP_EXCEPTION_OP || f==VP_EXCEPTION_MEMORY) always = 1;
|
if(f==VP_EXCEPTION_OP || f==VP_EXCEPTION_MEMORY) always = 1;
|
||||||
|
|
||||||
if(always||(gfDoException&f)) {
|
if (always || (exception_mode & f)) {
|
||||||
switch(f)
|
switch(f)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -4429,7 +4505,7 @@ Exit:
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
VP_EXPORT int
|
VP_EXPORT int
|
||||||
VpMidRound(Real *y, int f, ssize_t nf)
|
VpMidRound(Real *y, unsigned short f, ssize_t nf)
|
||||||
/*
|
/*
|
||||||
* Round reletively from the decimal point.
|
* Round reletively from the decimal point.
|
||||||
* f: rounding mode
|
* f: rounding mode
|
||||||
@ -4539,7 +4615,7 @@ VpMidRound(Real *y, int f, ssize_t nf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT int
|
VP_EXPORT int
|
||||||
VpLeftRound(Real *y, int f, ssize_t nf)
|
VpLeftRound(Real *y, unsigned short f, ssize_t nf)
|
||||||
/*
|
/*
|
||||||
* Round from the left hand side of the digits.
|
* Round from the left hand side of the digits.
|
||||||
*/
|
*/
|
||||||
@ -4554,7 +4630,7 @@ VpLeftRound(Real *y, int f, ssize_t nf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VP_EXPORT int
|
VP_EXPORT int
|
||||||
VpActiveRound(Real *y, Real *x, int f, ssize_t nf)
|
VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t nf)
|
||||||
{
|
{
|
||||||
/* First,assign whole value in truncation mode */
|
/* First,assign whole value in truncation mode */
|
||||||
if (VpAsgn(y, x, 10) <= 1) return 0; /* Zero,NaN,or Infinity */
|
if (VpAsgn(y, x, 10) <= 1) return 0; /* Zero,NaN,or Infinity */
|
||||||
@ -4577,11 +4653,13 @@ VpInternalRound(Real *c, size_t ixDigit, BDIGIT vPrev, BDIGIT v)
|
|||||||
{
|
{
|
||||||
int f = 0;
|
int f = 0;
|
||||||
|
|
||||||
|
unsigned short const rounding_mode = VpGetRoundMode();
|
||||||
|
|
||||||
if(VpLimitRound(c,ixDigit)) return;
|
if(VpLimitRound(c,ixDigit)) return;
|
||||||
if(!v) return;
|
if(!v) return;
|
||||||
|
|
||||||
v /= BASE1;
|
v /= BASE1;
|
||||||
switch(gfRoundMode) {
|
switch (rounding_mode) {
|
||||||
case VP_ROUND_DOWN:
|
case VP_ROUND_DOWN:
|
||||||
break;
|
break;
|
||||||
case VP_ROUND_UP:
|
case VP_ROUND_UP:
|
||||||
|
@ -98,6 +98,8 @@ extern VALUE rb_cBigDecimal;
|
|||||||
#define VP_EXCEPTION_OP ((unsigned short)0x0020)
|
#define VP_EXCEPTION_OP ((unsigned short)0x0020)
|
||||||
#define VP_EXCEPTION_MEMORY ((unsigned short)0x0040)
|
#define VP_EXCEPTION_MEMORY ((unsigned short)0x0040)
|
||||||
|
|
||||||
|
#define RMPD_EXCEPTION_MODE_DEFAULT 0U
|
||||||
|
|
||||||
/* Computation mode */
|
/* Computation mode */
|
||||||
#define VP_ROUND_MODE ((unsigned short)0x0100)
|
#define VP_ROUND_MODE ((unsigned short)0x0100)
|
||||||
#define VP_ROUND_UP 1
|
#define VP_ROUND_UP 1
|
||||||
@ -108,6 +110,8 @@ extern VALUE rb_cBigDecimal;
|
|||||||
#define VP_ROUND_FLOOR 6
|
#define VP_ROUND_FLOOR 6
|
||||||
#define VP_ROUND_HALF_EVEN 7
|
#define VP_ROUND_HALF_EVEN 7
|
||||||
|
|
||||||
|
#define RMPD_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP
|
||||||
|
|
||||||
#define VP_SIGN_NaN 0 /* NaN */
|
#define VP_SIGN_NaN 0 /* NaN */
|
||||||
#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */
|
#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */
|
||||||
#define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */
|
#define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */
|
||||||
@ -176,9 +180,9 @@ VP_EXPORT size_t VpGetPrecLimit(void);
|
|||||||
VP_EXPORT size_t VpSetPrecLimit(size_t n);
|
VP_EXPORT size_t VpSetPrecLimit(size_t n);
|
||||||
|
|
||||||
/* Round mode */
|
/* Round mode */
|
||||||
VP_EXPORT int VpIsRoundMode(unsigned long n);
|
VP_EXPORT int VpIsRoundMode(unsigned short n);
|
||||||
VP_EXPORT unsigned long VpGetRoundMode(void);
|
VP_EXPORT unsigned short VpGetRoundMode(void);
|
||||||
VP_EXPORT unsigned long VpSetRoundMode(unsigned long n);
|
VP_EXPORT unsigned short VpSetRoundMode(unsigned short n);
|
||||||
|
|
||||||
VP_EXPORT int VpException(unsigned short f,const char *str,int always);
|
VP_EXPORT int VpException(unsigned short f,const char *str,int always);
|
||||||
#if 0 /* unused */
|
#if 0 /* unused */
|
||||||
@ -206,9 +210,9 @@ VP_EXPORT void VpDtoV(Real *m,double d);
|
|||||||
VP_EXPORT void VpItoV(Real *m,S_INT ival);
|
VP_EXPORT void VpItoV(Real *m,S_INT ival);
|
||||||
#endif
|
#endif
|
||||||
VP_EXPORT int VpSqrt(Real *y,Real *x);
|
VP_EXPORT int VpSqrt(Real *y,Real *x);
|
||||||
VP_EXPORT int VpActiveRound(Real *y, Real *x, int f, ssize_t il);
|
VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il);
|
||||||
VP_EXPORT int VpMidRound(Real *y, int f, ssize_t nf);
|
VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf);
|
||||||
VP_EXPORT int VpLeftRound(Real *y, int f, ssize_t nf);
|
VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf);
|
||||||
VP_EXPORT void VpFrac(Real *y, Real *x);
|
VP_EXPORT void VpFrac(Real *y, Real *x);
|
||||||
VP_EXPORT int VpPower(Real *y, Real *x, SIGNED_VALUE n);
|
VP_EXPORT int VpPower(Real *y, Real *x, SIGNED_VALUE n);
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
require_relative "testbase"
|
require_relative "testbase"
|
||||||
|
|
||||||
|
require 'thread'
|
||||||
|
|
||||||
class TestBigDecimal < Test::Unit::TestCase
|
class TestBigDecimal < Test::Unit::TestCase
|
||||||
include TestBigDecimalBase
|
include TestBigDecimalBase
|
||||||
|
|
||||||
@ -40,6 +42,39 @@ class TestBigDecimal < Test::Unit::TestCase
|
|||||||
assert_raise(TypeError) { BigDecimal.mode(BigDecimal::EXCEPTION_ALL, 1) }
|
assert_raise(TypeError) { BigDecimal.mode(BigDecimal::EXCEPTION_ALL, 1) }
|
||||||
assert_raise(TypeError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 256) }
|
assert_raise(TypeError) { BigDecimal.mode(BigDecimal::ROUND_MODE, 256) }
|
||||||
assert_raise(TypeError) { BigDecimal.mode(0xf000, true) }
|
assert_raise(TypeError) { BigDecimal.mode(0xf000, true) }
|
||||||
|
|
||||||
|
begin
|
||||||
|
saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
|
||||||
|
|
||||||
|
[ BigDecimal::ROUND_UP,
|
||||||
|
BigDecimal::ROUND_DOWN,
|
||||||
|
BigDecimal::ROUND_HALF_UP,
|
||||||
|
BigDecimal::ROUND_HALF_DOWN,
|
||||||
|
BigDecimal::ROUND_CEILING,
|
||||||
|
BigDecimal::ROUND_FLOOR,
|
||||||
|
BigDecimal::ROUND_HALF_EVEN,
|
||||||
|
].each do |mode|
|
||||||
|
BigDecimal.mode(BigDecimal::ROUND_MODE, mode)
|
||||||
|
assert_equal(mode, BigDecimal.mode(BigDecimal::ROUND_MODE))
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_thread_local_mode
|
||||||
|
begin
|
||||||
|
saved_mode = BigDecimal.mode(BigDecimal::ROUND_MODE)
|
||||||
|
|
||||||
|
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_UP)
|
||||||
|
Thread.start {
|
||||||
|
BigDecimal.mode(BigDecimal::ROUND_MODE, BigDecimal::ROUND_HALF_EVEN)
|
||||||
|
assert_equal(BigDecimal::ROUND_HALF_EVEN, BigDecimal.mode(BigDecimal::ROUND_MODE))
|
||||||
|
}.join
|
||||||
|
assert_equal(BigDecimal::ROUND_UP, BigDecimal.mode(BigDecimal::ROUND_MODE))
|
||||||
|
ensure
|
||||||
|
BigDecimal.mode(BigDecimal::ROUND_MODE, saved_mode)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_exception_nan
|
def test_exception_nan
|
||||||
|
Loading…
x
Reference in New Issue
Block a user