summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2010-06-16 12:47:40 -0400
committerRich Hickey <richhickey@gmail.com>2010-06-16 12:47:40 -0400
commita1a25da6b717af52cbd4e5c5e87de921ec8478eb (patch)
tree6758ca6cce86cc4b22749aad01599f53928546bd
parentd97599c35c4cf252d4ecf2a33d9af5c24ac82fa6 (diff)
return bigints from ratio ops only when bigint operand
-rw-r--r--src/jvm/clojure/lang/LispReader.java3
-rw-r--r--src/jvm/clojure/lang/Numbers.java26
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;