End of Life Ruby 3.0 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
BigDecimal.mode
static VALUE
BigDecimal_mode(int argc, VALUE *argv, VALUE self)
{
VALUE which;
VALUE val;
unsigned long f,fo;
rb_scan_args(argc, argv, "11", &which, &val);
f = (unsigned long)NUM2INT(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;
}
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)