Method: BigDecimal.mode
- Defined in:
- bigdecimal.c
.mode(mode, setting = nil) ⇒ Integer
Returns an integer representing the mode settings for exception handling and rounding.
These modes control exception handling:
-
BigDecimal::EXCEPTION_NaN.
-
BigDecimal::EXCEPTION_INFINITY.
-
BigDecimal::EXCEPTION_UNDERFLOW.
-
BigDecimal::EXCEPTION_OVERFLOW.
-
BigDecimal::EXCEPTION_ZERODIVIDE.
-
BigDecimal::EXCEPTION_ALL.
Values for setting
for exception handling:
-
true
: sets the givenmode
totrue
. -
false
: sets the givenmode
tofalse
. -
nil
: does not modify the mode settings.
You can use method BigDecimal.save_exception_mode to temporarily change, and then automatically restore, exception modes.
For clarity, some examples below begin by setting all exception modes to false
.
This mode controls the way rounding is to be performed:
-
BigDecimal::ROUND_MODE
You can use method BigDecimal.save_rounding_mode to temporarily change, and then automatically restore, the rounding mode.
NaNs
Mode BigDecimal::EXCEPTION_NaN controls behavior when a BigDecimal NaN is created.
Settings:
-
false
(default): ReturnsBigDecimal('NaN')
. -
true
: Raises FloatDomainError.
Examples:
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0
BigDecimal('NaN') # => NaN
BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true) # => 2
BigDecimal('NaN') # Raises FloatDomainError
Infinities
Mode BigDecimal::EXCEPTION_INFINITY controls behavior when a BigDecimal Infinity or -Infinity is created. Settings:
-
false
(default): ReturnsBigDecimal('Infinity')
orBigDecimal('-Infinity')
. -
true
: Raises FloatDomainError.
Examples:
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0
BigDecimal('Infinity') # => Infinity
BigDecimal('-Infinity') # => -Infinity
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true) # => 1
BigDecimal('Infinity') # Raises FloatDomainError
BigDecimal('-Infinity') # Raises FloatDomainError
Underflow
Mode BigDecimal::EXCEPTION_UNDERFLOW controls behavior when a BigDecimal underflow occurs. Settings:
-
false
(default): ReturnsBigDecimal('0')
orBigDecimal('-Infinity')
. -
true
: Raises FloatDomainError.
Examples:
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0
def flow_under
x = BigDecimal('0.1')
100.times { x *= x }
end
flow_under # => 100
BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true) # => 4
flow_under # Raises FloatDomainError
Overflow
Mode BigDecimal::EXCEPTION_OVERFLOW controls behavior when a BigDecimal overflow occurs. Settings:
-
false
(default): ReturnsBigDecimal('Infinity')
orBigDecimal('-Infinity')
. -
true
: Raises FloatDomainError.
Examples:
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0
def flow_over
x = BigDecimal('10')
100.times { x *= x }
end
flow_over # => 100
BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true) # => 1
flow_over # Raises FloatDomainError
Zero Division
Mode BigDecimal::EXCEPTION_ZERODIVIDE controls behavior when a zero-division occurs. Settings:
-
false
(default): ReturnsBigDecimal('Infinity')
orBigDecimal('-Infinity')
. -
true
: Raises FloatDomainError.
Examples:
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0
one = BigDecimal('1')
zero = BigDecimal('0')
one / zero # => Infinity
BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, true) # => 16
one / zero # Raises FloatDomainError
All Exceptions
Mode BigDecimal::EXCEPTION_ALL controls all of the above:
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0
BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true) # => 23
Rounding
Mode BigDecimal::ROUND_MODE controls the way rounding is to be performed; its setting
values are:
-
ROUND_UP
: Round away from zero. Aliased as:up
. -
ROUND_DOWN
: Round toward zero. Aliased as:down
and:truncate
. -
ROUND_HALF_UP
: Round toward the nearest neighbor; if the neighbors are equidistant, round away from zero. Aliased as:half_up
and:default
. -
ROUND_HALF_DOWN
: Round toward the nearest neighbor; if the neighbors are equidistant, round toward zero. Aliased as:half_down
. -
ROUND_HALF_EVEN
(Banker’s rounding): Round toward the nearest neighbor; if the neighbors are equidistant, round toward the even neighbor. Aliased as:half_even
and:banker
. -
ROUND_CEILING
: Round toward positive infinity. Aliased as:ceiling
and:ceil
. -
ROUND_FLOOR
: Round toward negative infinity. Aliased as:floor:
.
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 |
# File 'bigdecimal.c', line 1064
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;
}
|