diff --git a/lib/bigdecimal.rb b/lib/bigdecimal.rb index c23005ed..40d9cffc 100644 --- a/lib/bigdecimal.rb +++ b/lib/bigdecimal.rb @@ -46,7 +46,8 @@ def power(y, prec = nil) x = self y = BigMath._coerce_to_bigdecimal(y, :power) - return BigDecimal::NAN if x.nan? || y.nan? + return BigMath._nan_computation_result if x.nan? || y.nan? + return BigDecimal(1) if y.zero? if y.infinite? if x < 0 @@ -54,21 +55,27 @@ def power(y, prec = nil) return BigDecimal(0) if x > -1 && y.positive? raise Math::DomainError, 'Result undefined for negative base raised to infinite power' elsif x < 1 - return y.positive? ? BigDecimal(0) : BigDecimal::INFINITY + return y.positive? ? BigDecimal(0) : BigMath._infinity_computation_result elsif x == 1 return BigDecimal(1) else - return y.positive? ? BigDecimal::INFINITY : BigDecimal(0) + return y.positive? ? BigMath._infinity_computation_result : BigDecimal(0) end end + if x.infinite? && y < 0 + # Computation result will be +0 or -0. Avoid overflow. + neg = x < 0 && y.frac.zero? && y % 2 == 1 + return neg ? -BigDecimal(0) : BigDecimal(0) + end + if x.zero? return BigDecimal(1) if y.zero? return BigDecimal(0) if y > 0 if y.frac.zero? && y % 2 == 1 && x.sign == -1 - return -BigDecimal::INFINITY + return -BigMath._infinity_computation_result else - return BigDecimal::INFINITY + return BigMath._infinity_computation_result end elsif x < 0 if y.frac.zero? @@ -101,7 +108,7 @@ def power(y, prec = nil) xn *= xn # Detect overflow/underflow before consuming infinite memory if (xn.exponent.abs - 1) * int_part / n >= 0x7FFFFFFFFFFFFFFF - return ((xn.exponent > 0) ^ neg ? BigDecimal::INFINITY : BigDecimal(0)) * (int_part.even? || x > 0 ? 1 : -1) + return ((xn.exponent > 0) ^ neg ? BigMath._infinity_computation_result : BigDecimal(0)) * (int_part.even? || x > 0 ? 1 : -1) end end return neg ? BigDecimal(1) / ans : ans @@ -112,7 +119,7 @@ def power(y, prec = nil) if y < 0 inv = x.power(-y, prec) return BigDecimal(0) if inv.infinite? - return BigDecimal::INFINITY if inv.zero? + return BigMath._infinity_computation_result if inv.zero? return BigDecimal(1).div(inv, prec) end @@ -138,7 +145,7 @@ def power(y, prec = nil) # Core BigMath methods for BigDecimal (log, exp) are defined here. # Other methods (sin, cos, atan) are defined in 'bigdecimal/math.rb'. module BigMath - def self._coerce_to_bigdecimal(x, method_name, complex_domain_error = false) + def self._coerce_to_bigdecimal(x, method_name, complex_domain_error = false) # :nodoc: case x when BigDecimal return x @@ -152,11 +159,25 @@ def self._coerce_to_bigdecimal(x, method_name, complex_domain_error = false) raise ArgumentError, "#{x.inspect} can't be coerced into BigDecimal" end - def self._validate_prec(prec, method_name) + def self._validate_prec(prec, method_name) # :nodoc: raise ArgumentError, 'precision must be an Integer' unless Integer === prec raise ArgumentError, "Zero or negative precision for #{method_name}" if prec <= 0 end + def self._infinity_computation_result # :nodoc: + if BigDecimal.mode(BigDecimal::EXCEPTION_ALL).anybits?(BigDecimal::EXCEPTION_INFINITY) + raise FloatDomainError, "Computation results in 'Infinity'" + end + BigDecimal::INFINITY + end + + def self._nan_computation_result # :nodoc: + if BigDecimal.mode(BigDecimal::EXCEPTION_ALL).anybits?(BigDecimal::EXCEPTION_NaN) + raise FloatDomainError, "Computation results to 'NaN'" + end + BigDecimal::NAN + end + # call-seq: # BigMath.log(decimal, numeric) -> BigDecimal # @@ -172,9 +193,9 @@ def self._validate_prec(prec, method_name) def self.log(x, prec) _validate_prec(prec, :log) x = _coerce_to_bigdecimal(x, :log, true) - return BigDecimal::NAN if x.nan? + return _nan_computation_result if x.nan? raise Math::DomainError, 'Zero or negative argument for log' if x <= 0 - return BigDecimal::INFINITY if x.infinite? + return _infinity_computation_result if x.infinite? return BigDecimal(0) if x == 1 if x > 10 || x < 0.1 @@ -238,8 +259,8 @@ def self.log(x, prec) def self.exp(x, prec) _validate_prec(prec, :exp) x = _coerce_to_bigdecimal(x, :exp) - return BigDecimal::NAN if x.nan? - return x.positive? ? BigDecimal::INFINITY : BigDecimal(0) if x.infinite? + return _nan_computation_result if x.nan? + return x.positive? ? _infinity_computation_result : BigDecimal(0) if x.infinite? return BigDecimal(1) if x.zero? return BigDecimal(1).div(exp(-x, prec), prec) if x < 0 diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb index 53b4fc77..59a39c6d 100644 --- a/test/bigdecimal/test_bigdecimal.rb +++ b/test/bigdecimal/test_bigdecimal.rb @@ -32,6 +32,8 @@ class TestBigDecimal < Test::Unit::TestCase EXPONENT_MAX = LIMITS['INTPTR_MAX'] / BASE_FIG * BASE_FIG EXPONENT_MIN = (LIMITS['INTPTR_MIN'] - 2) / BASE_FIG * BASE_FIG + BASE_FIG + 1 + NEGATIVE_INFINITY = -BigDecimal::INFINITY + ROUNDING_MODE_MAP = [ [ BigDecimal::ROUND_UP, :up], [ BigDecimal::ROUND_DOWN, :down], @@ -60,6 +62,32 @@ def assert_negative_infinite(x) assert_operator(x, :<, 0) end + def assert_infinite_calculation(positive:) + BigDecimal.save_exception_mode do + BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) + positive ? assert_positive_infinite(yield) : assert_negative_infinite(yield) + BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true) + assert_raise_with_message(FloatDomainError, /Infinity/) { yield } + end + end + + def assert_positive_infinite_calculation(&block) + assert_infinite_calculation(positive: true, &block) + end + + def assert_negative_infinite_calculation(&block) + assert_infinite_calculation(positive: false, &block) + end + + def assert_nan_calculation(&block) + BigDecimal.save_exception_mode do + BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) + assert_nan(yield) + BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true) + assert_raise_with_message(FloatDomainError, /NaN/) { yield } + end + end + def assert_positive_zero(x) assert_equal(BigDecimal::SIGN_POSITIVE_ZERO, x.sign, "Expected #{x.inspect} to be positive zero") @@ -1650,38 +1678,35 @@ def test_power_with_nil end def test_power_of_nan - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) - assert_nan(BigDecimal::NAN ** 0) - assert_nan(BigDecimal::NAN ** 1) - assert_nan(BigDecimal::NAN ** 42) - assert_nan(BigDecimal::NAN ** -42) - assert_nan(BigDecimal::NAN ** 42.0) - assert_nan(BigDecimal::NAN ** -42.0) - assert_nan(BigDecimal::NAN ** BigDecimal(42)) - assert_nan(BigDecimal::NAN ** BigDecimal(-42)) - assert_nan(BigDecimal::NAN ** BigDecimal::INFINITY) - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) - assert_nan(BigDecimal::NAN ** (-BigDecimal::INFINITY)) - end - end + assert_nan_calculation { BigDecimal::NAN ** 0 } + assert_nan_calculation { BigDecimal::NAN ** 1 } + assert_nan_calculation { BigDecimal::NAN ** 42 } + assert_nan_calculation { BigDecimal::NAN ** -42 } + assert_nan_calculation { BigDecimal::NAN ** 42.0 } + assert_nan_calculation { BigDecimal::NAN ** -42.0 } + assert_nan_calculation { BigDecimal::NAN ** BigDecimal(42) } + assert_nan_calculation { BigDecimal::NAN ** BigDecimal(-42) } + assert_nan_calculation { BigDecimal::NAN ** BigDecimal::INFINITY } + assert_nan_calculation { BigDecimal::NAN ** NEGATIVE_INFINITY } end def test_power_with_Bignum + assert_equal(0, BigDecimal(0) ** (2**100)) + + assert_positive_infinite_calculation { BigDecimal(0) ** -(2**100) } + assert_positive_infinite_calculation { BigDecimal(0) ** -(2**100 + 1) } + assert_positive_infinite_calculation { (-BigDecimal(0)) ** -(2**100) } + assert_negative_infinite_calculation { (-BigDecimal(0)) ** -(2**100 + 1) } + + assert_equal(1, BigDecimal(1) ** (2**100)) + assert_equal(1, BigDecimal(-1) ** (2**100)) + assert_equal(1, BigDecimal(1) ** (2**100 + 1)) + assert_equal(-1, BigDecimal(-1) ** (2**100 + 1)) + BigDecimal.save_exception_mode do BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, false) - assert_equal(0, BigDecimal(0) ** (2**100)) - - assert_positive_infinite(BigDecimal(0) ** -(2**100)) - assert_positive_infinite((-BigDecimal(0)) ** -(2**100)) - assert_negative_infinite((-BigDecimal(0)) ** -(2**100 + 1)) - - assert_equal(1, BigDecimal(1) ** (2**100)) - assert_equal(1, BigDecimal(-1) ** (2**100)) - assert_equal(1, BigDecimal(1) ** (2**100 + 1)) - assert_equal(-1, BigDecimal(-1) ** (2**100 + 1)) + # TODO: Add test and implementation for underflow and overflow errors assert_positive_infinite(BigDecimal(3) ** (2**100)) assert_positive_zero(BigDecimal(3) ** (-2**100)) @@ -1748,113 +1773,101 @@ def test_power_of_zero assert_equal(1, zero ** 0.quo(1)) assert_equal(1, zero ** 0.0) assert_equal(1, zero ** BigDecimal(0)) - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) - BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) - assert_positive_infinite(zero ** -1) - assert_positive_infinite(zero ** -1.quo(1)) - assert_positive_infinite(zero ** -1.0) - assert_positive_infinite(zero ** BigDecimal(-1)) - m_zero = BigDecimal("-0") - assert_negative_infinite(m_zero ** -1) - assert_negative_infinite(m_zero ** -1.quo(1)) - assert_negative_infinite(m_zero ** -1.0) - assert_negative_infinite(m_zero ** BigDecimal(-1)) - assert_positive_infinite(m_zero ** -2) - assert_positive_infinite(m_zero ** -2.quo(1)) - assert_positive_infinite(m_zero ** -2.0) - assert_positive_infinite(m_zero ** BigDecimal(-2)) - end + assert_positive_infinite_calculation { zero ** -1 } + assert_positive_infinite_calculation { zero ** -1.quo(1) } + assert_positive_infinite_calculation { zero ** -1.0 } + assert_positive_infinite_calculation { zero ** BigDecimal(-1) } + + m_zero = BigDecimal("-0") + assert_negative_infinite_calculation { m_zero ** -1 } + assert_negative_infinite_calculation { m_zero ** -1.quo(1) } + assert_negative_infinite_calculation { m_zero ** -1.0 } + assert_negative_infinite_calculation { m_zero ** BigDecimal(-1) } + assert_positive_infinite_calculation { m_zero ** -2 } + assert_positive_infinite_calculation { m_zero ** -2.quo(1) } + assert_positive_infinite_calculation { m_zero ** -2.0 } + assert_positive_infinite_calculation { m_zero ** BigDecimal(-2) } end def test_power_of_positive_infinity - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) - assert_positive_infinite(BigDecimal::INFINITY ** 3) - assert_positive_infinite(BigDecimal::INFINITY ** 3.quo(1)) - assert_positive_infinite(BigDecimal::INFINITY ** 3.0) - assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(3)) - assert_positive_infinite(BigDecimal::INFINITY ** 2) - assert_positive_infinite(BigDecimal::INFINITY ** 2.quo(1)) - assert_positive_infinite(BigDecimal::INFINITY ** 2.0) - assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(2)) - assert_positive_infinite(BigDecimal::INFINITY ** 1) - assert_positive_infinite(BigDecimal::INFINITY ** 1.quo(1)) - assert_positive_infinite(BigDecimal::INFINITY ** 1.0) - assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal(1)) - assert_equal(1, BigDecimal::INFINITY ** 0) - assert_equal(1, BigDecimal::INFINITY ** 0.quo(1)) - assert_equal(1, BigDecimal::INFINITY ** 0.0) - assert_equal(1, BigDecimal::INFINITY ** BigDecimal(0)) - assert_positive_zero(BigDecimal::INFINITY ** -1) - assert_positive_zero(BigDecimal::INFINITY ** -1.quo(1)) - assert_positive_zero(BigDecimal::INFINITY ** -1.0) - assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-1)) - assert_positive_zero(BigDecimal::INFINITY ** -2) - assert_positive_zero(BigDecimal::INFINITY ** -2.0) - assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-2)) - end + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 3 } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 3.quo(1) } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 3.0 } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** BigDecimal(3) } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 2 } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 2.quo(1) } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 2.0 } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** BigDecimal(2) } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 1 } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 1.quo(1) } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** 1.0 } + assert_positive_infinite_calculation { BigDecimal::INFINITY ** BigDecimal(1) } + assert_equal(1, BigDecimal::INFINITY ** 0) + assert_equal(1, BigDecimal::INFINITY ** 0.quo(1)) + assert_equal(1, BigDecimal::INFINITY ** 0.0) + assert_equal(1, BigDecimal::INFINITY ** BigDecimal(0)) + assert_positive_zero(BigDecimal::INFINITY ** -1) + assert_positive_zero(BigDecimal::INFINITY ** -1.quo(1)) + assert_positive_zero(BigDecimal::INFINITY ** -1.0) + assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-1)) + assert_positive_zero(BigDecimal::INFINITY ** -2) + assert_positive_zero(BigDecimal::INFINITY ** -2.0) + assert_positive_zero(BigDecimal::INFINITY ** BigDecimal(-2)) end def test_power_of_negative_infinity - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) - assert_negative_infinite((-BigDecimal::INFINITY) ** 3) - assert_negative_infinite((-BigDecimal::INFINITY) ** 3.quo(1)) - assert_negative_infinite((-BigDecimal::INFINITY) ** 3.0) - assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(3)) - assert_positive_infinite((-BigDecimal::INFINITY) ** 2) - assert_positive_infinite((-BigDecimal::INFINITY) ** 2.quo(1)) - assert_positive_infinite((-BigDecimal::INFINITY) ** 2.0) - assert_positive_infinite((-BigDecimal::INFINITY) ** BigDecimal(2)) - assert_negative_infinite((-BigDecimal::INFINITY) ** 1) - assert_negative_infinite((-BigDecimal::INFINITY) ** 1.quo(1)) - assert_negative_infinite((-BigDecimal::INFINITY) ** 1.0) - assert_negative_infinite((-BigDecimal::INFINITY) ** BigDecimal(1)) - assert_equal(1, (-BigDecimal::INFINITY) ** 0) - assert_equal(1, (-BigDecimal::INFINITY) ** 0.quo(1)) - assert_equal(1, (-BigDecimal::INFINITY) ** 0.0) - assert_equal(1, (-BigDecimal::INFINITY) ** BigDecimal(0)) - assert_negative_zero((-BigDecimal::INFINITY) ** -1) - assert_negative_zero((-BigDecimal::INFINITY) ** -1.quo(1)) - assert_negative_zero((-BigDecimal::INFINITY) ** -1.0) - assert_negative_zero((-BigDecimal::INFINITY) ** BigDecimal(-1)) - assert_positive_zero((-BigDecimal::INFINITY) ** -2) - assert_positive_zero((-BigDecimal::INFINITY) ** -2.quo(1)) - assert_positive_zero((-BigDecimal::INFINITY) ** -2.0) - assert_positive_zero((-BigDecimal::INFINITY) ** BigDecimal(-2)) - end + assert_negative_infinite_calculation { NEGATIVE_INFINITY ** 3 } + assert_negative_infinite_calculation { NEGATIVE_INFINITY ** 3.quo(1) } + assert_negative_infinite_calculation { NEGATIVE_INFINITY ** 3.0 } + assert_negative_infinite_calculation { NEGATIVE_INFINITY ** BigDecimal(3) } + assert_positive_infinite_calculation { NEGATIVE_INFINITY ** 2 } + assert_positive_infinite_calculation { NEGATIVE_INFINITY ** 2.quo(1) } + assert_positive_infinite_calculation { NEGATIVE_INFINITY ** 2.0 } + assert_positive_infinite_calculation { NEGATIVE_INFINITY ** BigDecimal(2) } + assert_negative_infinite_calculation { NEGATIVE_INFINITY ** 1 } + assert_negative_infinite_calculation { NEGATIVE_INFINITY ** 1.quo(1) } + assert_negative_infinite_calculation { NEGATIVE_INFINITY ** 1.0 } + assert_negative_infinite_calculation { NEGATIVE_INFINITY ** BigDecimal(1) } + assert_equal(1, NEGATIVE_INFINITY ** 0) + assert_equal(1, NEGATIVE_INFINITY ** 0.quo(1)) + assert_equal(1, NEGATIVE_INFINITY ** 0.0) + assert_equal(1, NEGATIVE_INFINITY ** BigDecimal(0)) + assert_negative_zero(NEGATIVE_INFINITY ** -1) + assert_negative_zero(NEGATIVE_INFINITY ** -1.quo(1)) + assert_negative_zero(NEGATIVE_INFINITY ** -1.0) + assert_negative_zero(NEGATIVE_INFINITY ** BigDecimal(-1)) + assert_positive_zero(NEGATIVE_INFINITY ** -2) + assert_positive_zero(NEGATIVE_INFINITY ** -2.quo(1)) + assert_positive_zero(NEGATIVE_INFINITY ** -2.0) + assert_positive_zero(NEGATIVE_INFINITY ** BigDecimal(-2)) end def test_infinite_power - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) - assert_positive_infinite(BigDecimal::INFINITY ** BigDecimal::INFINITY) - assert_positive_zero(BigDecimal::INFINITY ** -BigDecimal::INFINITY) - assert_positive_infinite(BigDecimal(3) ** BigDecimal::INFINITY) - assert_positive_zero(BigDecimal(3) ** -BigDecimal::INFINITY) - assert_positive_zero(BigDecimal("0.5") ** BigDecimal::INFINITY) - assert_positive_infinite(BigDecimal("0.5") ** -BigDecimal::INFINITY) - assert_equal(1, BigDecimal(1) ** BigDecimal::INFINITY) - assert_equal(1, BigDecimal(1) ** -BigDecimal::INFINITY) - assert_positive_zero(BigDecimal(0) ** BigDecimal::INFINITY) - assert_positive_infinite(BigDecimal(0) ** -BigDecimal::INFINITY) - assert_positive_zero(BigDecimal(-0.0) ** BigDecimal::INFINITY) - assert_positive_infinite(BigDecimal(-0.0) ** -BigDecimal::INFINITY) - - # negative_number ** infinite_number converge to zero - assert_positive_zero(BigDecimal(-2) ** -BigDecimal::INFINITY) - assert_positive_zero(BigDecimal(-0.5) ** BigDecimal::INFINITY) - assert_positive_zero((-BigDecimal::INFINITY) ** -BigDecimal::INFINITY) - - # negative_number ** infinite_number that does not converge - assert_raise(Math::DomainError) { BigDecimal(-2) ** BigDecimal::INFINITY } - assert_raise(Math::DomainError) { BigDecimal(-0.5) ** -BigDecimal::INFINITY } - assert_raise(Math::DomainError) { BigDecimal(-1) ** BigDecimal::INFINITY } - assert_raise(Math::DomainError) { BigDecimal(-1) ** -BigDecimal::INFINITY } - assert_raise(Math::DomainError) { (-BigDecimal::INFINITY) ** BigDecimal::INFINITY } - end + assert_positive_infinite_calculation { BigDecimal::INFINITY ** BigDecimal::INFINITY } + assert_positive_zero(BigDecimal::INFINITY ** NEGATIVE_INFINITY) + assert_positive_infinite_calculation { BigDecimal(3) ** BigDecimal::INFINITY } + assert_positive_zero(BigDecimal(3) ** NEGATIVE_INFINITY) + assert_positive_zero(BigDecimal("0.5") ** BigDecimal::INFINITY) + assert_positive_infinite_calculation { BigDecimal("0.5") ** NEGATIVE_INFINITY } + assert_equal(1, BigDecimal(1) ** BigDecimal::INFINITY) + assert_equal(1, BigDecimal(1) ** NEGATIVE_INFINITY) + assert_positive_zero(BigDecimal(0) ** BigDecimal::INFINITY) + assert_positive_infinite_calculation { BigDecimal(0) ** NEGATIVE_INFINITY } + assert_positive_zero(BigDecimal(-0.0) ** BigDecimal::INFINITY) + assert_positive_infinite_calculation { BigDecimal(-0.0) ** NEGATIVE_INFINITY } + + # negative_number ** infinite_number converge to zero + assert_positive_zero(BigDecimal(-2) ** NEGATIVE_INFINITY) + assert_positive_zero(BigDecimal(-0.5) ** BigDecimal::INFINITY) + assert_positive_zero(NEGATIVE_INFINITY ** NEGATIVE_INFINITY) + + # negative_number ** infinite_number that does not converge + assert_raise(Math::DomainError) { BigDecimal(-2) ** BigDecimal::INFINITY } + assert_raise(Math::DomainError) { BigDecimal(-0.5) ** NEGATIVE_INFINITY } + assert_raise(Math::DomainError) { BigDecimal(-1) ** BigDecimal::INFINITY } + assert_raise(Math::DomainError) { BigDecimal(-1) ** NEGATIVE_INFINITY } + assert_raise(Math::DomainError) { NEGATIVE_INFINITY ** BigDecimal::INFINITY } end def test_power_without_prec @@ -2094,25 +2107,15 @@ def test_exp_with_negative end def test_exp_with_negative_infinite - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) - assert_equal(0, BigMath.exp(-BigDecimal::INFINITY, 20)) - end + assert_equal(0, BigMath.exp(NEGATIVE_INFINITY, 20)) end def test_exp_with_positive_infinite - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) - assert(BigMath.exp(BigDecimal::INFINITY, 20) > 0) - assert_positive_infinite(BigMath.exp(BigDecimal::INFINITY, 20)) - end + assert_positive_infinite_calculation { BigMath.exp(BigDecimal::INFINITY, 20) } end def test_exp_with_nan - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) - assert_nan(BigMath.exp(BigDecimal::NAN, 20)) - end + assert_nan_calculation { BigMath.exp(BigDecimal::NAN, 20) } end def test_exp_with_1 @@ -2221,34 +2224,21 @@ def test_BigMath_log_with_negative_precision end def test_BigMath_log_with_negative_infinite - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) - assert_raise(Math::DomainError) do - BigMath.log(-BigDecimal::INFINITY, 20) - end + assert_raise(Math::DomainError) do + BigMath.log(NEGATIVE_INFINITY, 20) end end def test_BigMath_log_with_positive_infinite - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, false) - assert(BigMath.log(BigDecimal::INFINITY, 20) > 0) - assert_positive_infinite(BigMath.log(BigDecimal::INFINITY, 20)) - end + assert_positive_infinite_calculation { BigMath.log(BigDecimal::INFINITY, 20) } end def test_BigMath_log_with_nan - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) - assert_nan(BigMath.log(BigDecimal::NAN, 20)) - end + assert_nan_calculation { BigMath.log(BigDecimal::NAN, 20) } end def test_BigMath_log_with_float_nan - BigDecimal.save_exception_mode do - BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) - assert_nan(BigMath.log(Float::NAN, 20)) - end + assert_nan_calculation { BigMath.log(Float::NAN, 20) } end def test_BigMath_log_with_1