Skip to content

Commit

Permalink
Showing 2 changed files with 21 additions and 53 deletions.
29 changes: 18 additions & 11 deletions core/src/main/java/org/jruby/ext/bigdecimal/RubyBigDecimal.java
Original file line number Diff line number Diff line change
@@ -54,6 +54,7 @@
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyConstant;
import org.jruby.anno.JRubyMethod;
import org.jruby.ast.util.ArgsUtil;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.JavaSites;
@@ -326,30 +327,32 @@ public static IRubyObject mode(ThreadContext context, IRubyObject recv, IRubyObj
if (value.isNil()) return c.searchInternalModuleVariable("vpExceptionMode");
if (!(value instanceof RubyBoolean)) throw context.runtime.newArgumentError("second argument must be true or false");

RubyFixnum currentExceptionMode = (RubyFixnum)c.searchInternalModuleVariable("vpExceptionMode");
RubyFixnum newExceptionMode = new RubyFixnum(context.runtime, currentExceptionMode.getLongValue());
RubyFixnum newExceptionMode = (RubyFixnum)c.searchInternalModuleVariable("vpExceptionMode");

boolean enable = value.isTrue();

RubyFixnum _EXCEPTION_INFINITY = (RubyFixnum)clazz.getConstant("EXCEPTION_INFINITY");
if ((longMode & _EXCEPTION_INFINITY.getLongValue()) != 0) {
newExceptionMode = (value.isTrue()) ? (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_INFINITY)
: (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_INFINITY).getLongValue()));
newExceptionMode = enable ? (RubyFixnum)newExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_INFINITY)
: (RubyFixnum)newExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_INFINITY).getLongValue()));
}

RubyFixnum _EXCEPTION_NaN = (RubyFixnum)clazz.getConstant("EXCEPTION_NaN");
if ((longMode & _EXCEPTION_NaN.getLongValue()) != 0) {
newExceptionMode = (value.isTrue()) ? (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_NaN)
: (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_NaN).getLongValue()));
newExceptionMode = enable ? (RubyFixnum)newExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_NaN)
: (RubyFixnum)newExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_NaN).getLongValue()));
}

RubyFixnum _EXCEPTION_UNDERFLOW = (RubyFixnum)clazz.getConstant("EXCEPTION_UNDERFLOW");
if ((longMode & _EXCEPTION_UNDERFLOW.getLongValue()) != 0) {
newExceptionMode = (value.isTrue()) ? (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_UNDERFLOW)
: (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_UNDERFLOW).getLongValue()));
newExceptionMode = enable ? (RubyFixnum)newExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_UNDERFLOW)
: (RubyFixnum)newExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_UNDERFLOW).getLongValue()));
}

RubyFixnum _EXCEPTION_OVERFLOW = (RubyFixnum)clazz.getConstant("EXCEPTION_OVERFLOW");
if ((longMode & _EXCEPTION_OVERFLOW.getLongValue()) != 0) {
newExceptionMode = (value.isTrue()) ? (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_OVERFLOW)
: (RubyFixnum)currentExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_OVERFLOW).getLongValue()));
newExceptionMode = enable ? (RubyFixnum)newExceptionMode.callCoerced(context, sites(context).op_or, _EXCEPTION_OVERFLOW)
: (RubyFixnum)newExceptionMode.callCoerced(context, sites(context).op_and, new RubyFixnum(context.runtime, ~(_EXCEPTION_OVERFLOW).getLongValue()));
}
c.setInternalModuleVariable("vpExceptionMode", newExceptionMode);
return newExceptionMode;
@@ -1396,8 +1399,12 @@ public IRubyObject round(ThreadContext context, IRubyObject scale, IRubyObject m

//this relies on the Ruby rounding enumerations == Java ones, which they (currently) all are
private static RoundingMode javaRoundingModeFromRubyRoundingMode(Ruby runtime, IRubyObject arg) {
IRubyObject opts = ArgsUtil.getOptionsArg(runtime, arg);
if (!opts.isNil()) {
arg = ArgsUtil.extractKeywordArg(runtime.getCurrentContext(), "half", opts);
}
if (arg instanceof RubySymbol) {
String roundingMode = ((RubySymbol) arg).asJavaString();
String roundingMode = arg.asJavaString();
switch (roundingMode) {
case "up" :
return RoundingMode.UP;
45 changes: 3 additions & 42 deletions test/jruby/test_big_decimal.rb
Original file line number Diff line number Diff line change
@@ -5,8 +5,6 @@ class TestBigDecimal < Test::Unit::TestCase

def test_bad_to_s_format_strings
bd = BigDecimal.new("1")
assert_equal("0.1E1", bd.to_s)
assert_equal("+0.1E1", bd.to_s("+-2"))
assert_equal("0.23", BigDecimal.new("0.23").to_s("F"))
end

@@ -27,12 +25,6 @@ def test_can_implicitly_instantiate_big_decimal
assert_nothing_raised {BigDecimal("3.14159")}
end

def test_alphabetic_args_return_zero
assert_equal( BigDecimal("0.0"), BigDecimal("XXX"),
'Big Decimal objects instanitiated with a value that starts
with a letter should have a value of 0.0' )
end

class X
def to_str; "3.14159" end
end
@@ -183,7 +175,6 @@ def test_math_extension

def test_round_nan
nan = BigDecimal.new('NaN')
assert nan.round.nan? # nothing raised
assert nan.round(0).nan?
assert nan.round(2).nan?
end
@@ -213,13 +204,13 @@ def test_big_decimal_power
#assert_equal BigDecimal('0.125892541E2'), res
# NOTE: we're not handling precision the same as MRI with pow
assert_equal '0.125892541', res.to_s[0..10]
assert_equal 'E2', res.to_s[-2..-1]
assert_equal 'e2', res.to_s[-2..-1]

res = 2 ** BigDecimal(1.2, 2)
#assert_equal BigDecimal('0.229739671E1'), res
# NOTE: we're not handling precision the same as MRI with pow
assert_equal '0.22973967', res.to_s[0..9]
assert_equal 'E1', res.to_s[-2..-1]
assert_equal 'e1', res.to_s[-2..-1]

res = BigDecimal(1.2, 2) ** 2.0
assert_equal BigDecimal('0.144E1'), res
@@ -265,7 +256,7 @@ def test_big_decimal_mode
# note: this is to check compatibility with MRI, which currently sets only the last mode
# it checks for
BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY | BigDecimal::EXCEPTION_NaN, true)
assert_equal BigDecimal::EXCEPTION_NaN, BigDecimal.mode(1)
assert_equal BigDecimal::EXCEPTION_INFINITY | BigDecimal::EXCEPTION_NaN, BigDecimal.mode(1)

# rounding mode defaults to BigDecimal::ROUND_HALF_UP
assert_equal BigDecimal::ROUND_HALF_UP, BigDecimal.mode(BigDecimal::ROUND_MODE)
@@ -320,9 +311,6 @@ def test_infinity
#end

assert_raises(TypeError) { BigDecimal(:"+Infinity") }

assert_equal BigDecimal('0'), BigDecimal("infinity")
assert_equal BigDecimal('0'), BigDecimal("+Infinit")
end

#JRUBY-5190
@@ -355,32 +343,5 @@ def test_tail_junk
b = BigDecimal.new("100+42")
assert_equal 100, b.to_i
end

class BigDeci < BigDecimal

# MRI does not invoke initialize on 1.8./1.9
def initialize(arg); raise super(arg.to_s) end

def abs; -super end
def infinite?; false end

end

def test_subclass
a = BigDeci.new 1.to_s
assert_equal(-1, a.abs)
assert_equal false, a.infinite?

a = BigDeci.new '-100'
assert_equal(-5, a.div(20))
assert_equal(-100, a.abs)

assert a.inspect.index('#<BigDecimal:')
assert_equal '-0.1E3', a.to_s

assert_equal BigDeci, a.class
assert a.is_a?(BigDeci)
assert a.kind_of?(BigDeci)
end

end

0 comments on commit 03ba517

Please sign in to comment.