diff options
-rw-r--r-- | src/jvm/clojure/lang/LispReader.java | 3 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Numbers.java | 26 |
2 files changed, 21 insertions, 8 deletions
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java index 1d95c741..99ba6c17 100644 --- a/src/jvm/clojure/lang/LispReader.java +++ b/src/jvm/clojure/lang/LispReader.java @@ -360,7 +360,8 @@ private static Object matchNumber(String s){ m = ratioPat.matcher(s); if(m.matches()) { - return Numbers.divide(new BigInteger(m.group(1)), new BigInteger(m.group(2))); + return Numbers.divide(Numbers.reduceBigInteger(new BigInteger(m.group(1))), + Numbers.reduceBigInteger((new BigInteger(m.group(2))))); } return null; } diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java index a403395b..67eae153 100644 --- a/src/jvm/clojure/lang/Numbers.java +++ b/src/jvm/clojure/lang/Numbers.java @@ -607,26 +607,37 @@ final static class RatioOps implements Ops{ return r.numerator.signum() < 0; } + static Number normalizeRet(Number ret, Number x, Number y){ + if(ret instanceof BigInteger && !(x instanceof BigInteger || y instanceof BigInteger)) + { + return reduceBigInteger((BigInteger) ret); + } + return ret; + } + final public Number add(Number x, Number y){ Ratio rx = toRatio(x); Ratio ry = toRatio(y); - return divide(ry.numerator.multiply(rx.denominator) + Number ret = divide(ry.numerator.multiply(rx.denominator) .add(rx.numerator.multiply(ry.denominator)) , ry.denominator.multiply(rx.denominator)); + return normalizeRet(ret, x, y); } final public Number multiply(Number x, Number y){ Ratio rx = toRatio(x); Ratio ry = toRatio(y); - return Numbers.divide(ry.numerator.multiply(rx.numerator) + Number ret = Numbers.divide(ry.numerator.multiply(rx.numerator) , ry.denominator.multiply(rx.denominator)); + return normalizeRet(ret, x, y); } public Number divide(Number x, Number y){ Ratio rx = toRatio(x); Ratio ry = toRatio(y); - return Numbers.divide(ry.denominator.multiply(rx.numerator) + Number ret = Numbers.divide(ry.denominator.multiply(rx.numerator) , ry.numerator.multiply(rx.denominator)); + return normalizeRet(ret, x, y); } public Number quotient(Number x, Number y){ @@ -634,7 +645,7 @@ final static class RatioOps implements Ops{ Ratio ry = toRatio(y); BigInteger q = rx.numerator.multiply(ry.denominator).divide( rx.denominator.multiply(ry.numerator)); - return q; + return normalizeRet(q, x, y); } public Number remainder(Number x, Number y){ @@ -642,7 +653,8 @@ final static class RatioOps implements Ops{ Ratio ry = toRatio(y); BigInteger q = rx.numerator.multiply(ry.denominator).divide( rx.denominator.multiply(ry.numerator)); - return Numbers.minus(x, Numbers.multiply(q, y)); + Number ret = Numbers.minus(x, Numbers.multiply(q, y)); + return normalizeRet(ret, x, y); } public boolean equiv(Number x, Number y){ @@ -1012,11 +1024,11 @@ static final BigIntegerBitOps BIGINTEGER_BITOPS = new BigIntegerBitOps(); static Ops ops(Object x){ Class xc = x.getClass(); - if(xc == Long.class) + if(xc == Integer.class) return LONG_OPS; else if(xc == Double.class) return DOUBLE_OPS; - else if(xc == Integer.class) + else if(xc == Long.class) return LONG_OPS; else if(xc == Float.class) return DOUBLE_OPS; |