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 |
round away from zero
|
ROUND_DOWN |
round towards zero (truncate)
|
ROUND_HALF_UP |
round up if the appropriate digit
>= 5, otherwise truncate
(default)
|
ROUND_HALF_DOWN |
round up if the appropriate digit
>= 6, otherwise truncate
|
ROUND_HALF_EVEN |
round towards the even neighbor
(Banker’s rounding)
|
ROUND_CEILING |
round towards positive infinity (ceil)
|
ROUND_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_eTypeError, "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 */
fo = VpGetRoundMode();
if(val==Qnil) return INT2FIX(fo);
Check_Type(val, T_FIXNUM);
if(!VpIsRoundMode(FIX2INT(val))) {
rb_raise(rb_eTypeError, "invalid rounding mode");
return Qnil;
}
fo = VpSetRoundMode((unsigned long)FIX2INT(val));
return INT2FIX(fo);
}
rb_raise(rb_eTypeError, "first argument for BigDecimal#mode invalid");
return Qnil;
}