mode (p1, p2 = v2)
public
Controls handling of arithmetic exceptions and rounding. If no value is
supplied, the current value is returned.
Six values of the mode parameter
control the handling of arithmetic exceptions:
BigDecimal::EXCEPTION_NaN BigDecimal::EXCEPTION_INFINITY
BigDecimal::EXCEPTION_UNDERFLOW BigDecimal::EXCEPTION_OVERFLOW
BigDecimal::EXCEPTION_ZERODIVIDE BigDecimal::EXCEPTION_ALL
For each mode parameter above, if
the value set is false, computation continues after an arithmetic exception
of the appropriate type. When computation continues, results are as
follows:
EXCEPTION_NaN
NaN
EXCEPTION_INFINITY
+infinity or -infinity
EXCEPTION_UNDERFLOW
0
EXCEPTION_OVERFLOW
+infinity or -infinity
EXCEPTION_ZERODIVIDE
+infinity or -infinity
One value of the mode parameter
controls the rounding of numeric values: BigDecimal::ROUND_MODE. The values
it can take are:
ROUND_UP, :up
round away from zero
ROUND_DOWN, :down, :truncate
round towards zero (truncate )
ROUND_HALF_UP, :half_up, :default
round towards the nearest neighbor,
unless both neighbors are equidistant, in which case round away from zero. (default)
ROUND_HALF_DOWN, :half_down
round towards the nearest neighbor,
unless both neighbors are equidistant, in which case round towards zero.
ROUND_HALF_EVEN, :half_even, :banker
round towards the nearest neighbor,
unless both neighbors are equidistant, in which case round towards the even neighbor
(Banker’s rounding)
ROUND_CEILING, :ceiling, :ceil
round towards positive infinity (ceil )
ROUND_FLOOR, :floor
round towards negative infinity (floor )
Show source static VALUE
BigDecimal_mode(int argc, VALUE *argv, VALUE self)
{
VALUE which;
VALUE val;
unsigned long f,fo;
if(rb_scan_args(argc,argv,"11",&which,&val)==1) val = Qnil;
Check_Type(which, T_FIXNUM);
f = (unsigned long)FIX2INT(which);
if(f&VP_EXCEPTION_ALL) {
/* Exception mode setting */
fo = VpGetException();
if(val==Qnil) return INT2FIX(fo);
if(val!=Qfalse && val!=Qtrue) {
rb_raise(rb_eArgError, "second argument must be true or false");
return Qnil; /* Not reached */
}
if(f&VP_EXCEPTION_INFINITY) {
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) {
/* Rounding mode setting */
unsigned short sw;
fo = VpGetRoundMode();
if (NIL_P(val)) return INT2FIX(fo);
sw = check_rounding_mode(val);
fo = VpSetRoundMode(sw);
return INT2FIX(fo);
}
rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid");
return Qnil;
}