summaryrefslogtreecommitdiff
path: root/src/jvm/clojure
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-04-07 16:03:06 +0000
committerRich Hickey <richhickey@gmail.com>2008-04-07 16:03:06 +0000
commita6e022a6dbaed126101d7a39a1cec35cdd75d1a3 (patch)
tree4a5ff4fdb340d50c8580a5a4ff07a476e7e01c28 /src/jvm/clojure
parent7772fd99465cd9ebf494e12235d8f5288ed47df7 (diff)
more numbers experimentation
Diffstat (limited to 'src/jvm/clojure')
-rw-r--r--src/jvm/clojure/lang/Numbers.java198
1 files changed, 61 insertions, 137 deletions
diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java
index a7f509f7..418562ee 100644
--- a/src/jvm/clojure/lang/Numbers.java
+++ b/src/jvm/clojure/lang/Numbers.java
@@ -17,7 +17,26 @@ import java.math.BigDecimal;
public class Numbers{
-static public Object add(Object x, Object y){
+static interface Ops{
+ Ops combine(Ops y);
+ Ops opsWith(IntegerOps x);
+ Ops opsWith(FloatOps x);
+ Ops opsWith(DoubleOps x);
+ Ops opsWith(RatioOps x);
+ Ops opsWith(BigIntegerOps x);
+ Ops opsWith(BigDecimalOps x);
+
+ public Number add(Number x, Number y);
+ //public Number subtract(Number x, Number y);
+ public Number negate(Number x);
+}
+
+static public Number add(Number x, Number y){
+ return ops(x).combine(ops(y)).add(x, y);
+}
+
+static public Number subtract(Number x, Number y){
+ Ops yops = ops(y);
return ops(x).combine(ops(y)).add(x, y);
}
@@ -56,13 +75,11 @@ static Ratio toRatio(Object x){
static public Number reduce(BigInteger val){
if(val.bitLength() < 32)
return val.intValue();
- else if(val.bitLength() < 64)
- return val.longValue();
else
return val;
}
-static public Object divide(BigInteger n, BigInteger d){
+static public Number divide(BigInteger n, BigInteger d){
BigInteger gcd = n.gcd(d);
if(gcd.equals(BigInteger.ZERO))
return 0;
@@ -74,19 +91,6 @@ static public Object divide(BigInteger n, BigInteger d){
(d.signum() < 0 ? d.negate() : d));
}
-static interface Ops{
- Ops combine(Ops y);
- Ops opsWith(IntegerOps x);
- Ops opsWith(FloatOps x);
- Ops opsWith(DoubleOps x);
- Ops opsWith(RatioOps x);
- Ops opsWith(BigIntegerOps x);
- Ops opsWith(BigDecimalOps x);
- Ops opsWith(FloatArrayOps x);
- Ops opsWith(DoubleArrayOps x);
-
- public Object add(Object x, Object y);
-}
static class IntegerOps implements Ops{
public Ops combine(Ops y){
@@ -99,15 +103,18 @@ static class IntegerOps implements Ops{
final public Ops opsWith(RatioOps x){return RATIO_OPS;}
final public Ops opsWith(BigIntegerOps x){return BIGINTEGER_OPS;}
final public Ops opsWith(BigDecimalOps x){return BIGDECIMAL_OPS;}
- final public Ops opsWith(FloatArrayOps x){return FLOATARRAY_OPS;}
- final public Ops opsWith(DoubleArrayOps x){return DOUBLEARRAY_OPS;}
- final public Object add(Object x, Object y){
- long ret = ((Number) x).longValue() + ((Number) y).longValue();
+ final public Number add(Number x, Number y){
+ long ret = x.longValue() + y.longValue();
if(ret <= Integer.MAX_VALUE && ret >= Integer.MIN_VALUE)
return (int)ret;
return ret;
}
+
+ //public Number subtract(Number x, Number y);
+ public Number negate(Number x){
+ return -x.intValue();
+ }
}
static class FloatOps implements Ops{
@@ -121,11 +128,14 @@ static class FloatOps implements Ops{
final public Ops opsWith(RatioOps x){return this;}
final public Ops opsWith(BigIntegerOps x){return this;}
final public Ops opsWith(BigDecimalOps x){return this;}
- final public Ops opsWith(FloatArrayOps x){return FLOATARRAY_OPS;}
- final public Ops opsWith(DoubleArrayOps x){return DOUBLEARRAY_OPS;}
- final public Object add(Object x, Object y){
- return ((Number) x).floatValue() + ((Number) y).floatValue();
+ final public Number add(Number x, Number y){
+ return x.floatValue() + y.floatValue();
+ }
+
+ //public Number subtract(Number x, Number y);
+ public Number negate(Number x){
+ return -x.floatValue();
}
}
@@ -140,11 +150,14 @@ static class DoubleOps implements Ops{
final public Ops opsWith(RatioOps x){return this;}
final public Ops opsWith(BigIntegerOps x){return this;}
final public Ops opsWith(BigDecimalOps x){return this;}
- final public Ops opsWith(FloatArrayOps x){return FLOATARRAY_OPS;}
- final public Ops opsWith(DoubleArrayOps x){return DOUBLEARRAY_OPS;}
- final public Object add(Object x, Object y){
- return ((Number) x).doubleValue() + ((Number) y).doubleValue();
+ final public Number add(Number x, Number y){
+ return x.doubleValue() + y.doubleValue();
+ }
+
+ //public Number subtract(Number x, Number y);
+ public Number negate(Number x){
+ return -x.doubleValue();
}
}
@@ -159,16 +172,22 @@ static class RatioOps implements Ops{
final public Ops opsWith(RatioOps x){return this;}
final public Ops opsWith(BigIntegerOps x){return this;}
final public Ops opsWith(BigDecimalOps x){return this;}
- final public Ops opsWith(FloatArrayOps x){return FLOATARRAY_OPS;}
- final public Ops opsWith(DoubleArrayOps x){return DOUBLEARRAY_OPS;}
- final public Object add(Object x, Object y){
+ final public Number add(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
return divide(rx.numerator.multiply(rx.denominator)
.add(rx.numerator.multiply(ry.denominator))
, ry.denominator.multiply(rx.denominator));
}
+
+ //public Number subtract(Number x, Number y);
+ public Number negate(Number x){
+ Ratio r = (Ratio) x;
+ return new Ratio(r.numerator.negate(), r.denominator);
+ }
+
+
}
static class BigIntegerOps implements Ops{
public Ops combine(Ops y){
@@ -181,12 +200,15 @@ static class BigIntegerOps implements Ops{
final public Ops opsWith(RatioOps x){return RATIO_OPS;}
final public Ops opsWith(BigIntegerOps x){return this;}
final public Ops opsWith(BigDecimalOps x){return BIGDECIMAL_OPS;}
- final public Ops opsWith(FloatArrayOps x){return FLOATARRAY_OPS;}
- final public Ops opsWith(DoubleArrayOps x){return DOUBLEARRAY_OPS;}
- final public Object add(Object x, Object y){
+ final public Number add(Number x, Number y){
return reduce(toBigInteger(x).add(toBigInteger(y)));
}
+
+ //public Number subtract(Number x, Number y);
+ public Number negate(Number x){
+ return ((BigInteger)x).negate();
+ }
}
static class BigDecimalOps implements Ops{
@@ -200,103 +222,14 @@ static class BigDecimalOps implements Ops{
final public Ops opsWith(RatioOps x){return RATIO_OPS;}
final public Ops opsWith(BigIntegerOps x){return this;}
final public Ops opsWith(BigDecimalOps x){return this;}
- final public Ops opsWith(FloatArrayOps x){return FLOATARRAY_OPS;}
- final public Ops opsWith(DoubleArrayOps x){return DOUBLEARRAY_OPS;}
- final public Object add(Object x, Object y){
+ final public Number add(Number x, Number y){
return toBigDecimal(x).add(toBigDecimal(y));
}
-}
-static class FloatArrayOps implements Ops{
- public Ops combine(Ops y){
- return y.opsWith(this);
- }
-
- final boolean first;
-
- FloatArrayOps(boolean first){
- this.first = first;
- }
-
- final public Ops opsWith(IntegerOps x){return FLOATARRAY_OPS_REV;}
- final public Ops opsWith(FloatOps x){return FLOATARRAY_OPS_REV;}
- final public Ops opsWith(DoubleOps x){return FLOATARRAY_OPS_REV;}
- final public Ops opsWith(RatioOps x){return FLOATARRAY_OPS_REV;}
- final public Ops opsWith(BigIntegerOps x){return FLOATARRAY_OPS_REV;}
- final public Ops opsWith(BigDecimalOps x){return FLOATARRAY_OPS_REV;}
- final public Ops opsWith(FloatArrayOps x){return x;}
- final public Ops opsWith(DoubleArrayOps x){return x;}
-
- final public Object add(Object x, Object y){
- float[] a = (float[]) (first ? x : y);
- Object arg = first ? y : x;
- float[] ret = new float[a.length];
- if(arg instanceof Number)
- {
- float yd = ((Number) arg).floatValue();
- for(int i = 0; i < a.length; i++)
- ret[i] = a[i] + yd;
- }
- else if(arg instanceof double[])
- {
- double[] ya = (double[]) arg;
- for(int i = 0; i < a.length; i++)
- ret[i] = a[i] + (float) ya[i];
- }
- else
- {
- float[] ya = (float[]) arg;
- for(int i = 0; i < a.length; i++)
- ret[i] = a[i] + ya[i];
- }
- return ret;
- }
-}
-
-static class DoubleArrayOps implements Ops{
- public Ops combine(Ops y){
- return y.opsWith(this);
- }
-
- final boolean first;
-
- DoubleArrayOps(boolean first){
- this.first = first;
- }
-
- final public Ops opsWith(IntegerOps x){return DOUBLEARRAY_OPS_REV;}
- final public Ops opsWith(FloatOps x){return DOUBLEARRAY_OPS_REV;}
- final public Ops opsWith(DoubleOps x){return DOUBLEARRAY_OPS_REV;}
- final public Ops opsWith(RatioOps x){return DOUBLEARRAY_OPS_REV;}
- final public Ops opsWith(BigIntegerOps x){return DOUBLEARRAY_OPS_REV;}
- final public Ops opsWith(BigDecimalOps x){return DOUBLEARRAY_OPS_REV;}
- final public Ops opsWith(FloatArrayOps x){return DOUBLEARRAY_OPS_REV;}
- final public Ops opsWith(DoubleArrayOps x){return x;}
-
- final public Object add(Object x, Object y){
- double[] a = (double[]) (first ? x : y);
- Object arg = first ? y : x;
- double[] ret = new double[a.length];
- if(arg instanceof Number)
- {
- double yd = ((Number) arg).doubleValue();
- for(int i = 0; i < a.length; i++)
- ret[i] = a[i] + yd;
- }
- else if(arg instanceof double[])
- {
- double[] ya = (double[]) arg;
- for(int i = 0; i < a.length; i++)
- ret[i] = a[i] + ya[i];
- }
- else
- {
- float[] ya = (float[]) arg;
- for(int i = 0; i < a.length; i++)
- ret[i] = a[i] + ya[i];
- }
- return ret;
+ //public Number subtract(Number x, Number y);
+ public Number negate(Number x){
+ return ((BigDecimal)x).negate();
}
}
@@ -306,11 +239,6 @@ static final DoubleOps DOUBLE_OPS = new DoubleOps();
static final RatioOps RATIO_OPS = new RatioOps();
static final BigIntegerOps BIGINTEGER_OPS = new BigIntegerOps();
static final BigDecimalOps BIGDECIMAL_OPS = new BigDecimalOps();
-static final FloatArrayOps FLOATARRAY_OPS = new FloatArrayOps(true);
-static final DoubleArrayOps DOUBLEARRAY_OPS = new DoubleArrayOps(true);
-static final FloatArrayOps FLOATARRAY_OPS_REV = new FloatArrayOps(false);
-static final DoubleArrayOps DOUBLEARRAY_OPS_REV = new DoubleArrayOps(false);
-
static Ops ops(Object x){
Class xc = x.getClass();
@@ -327,10 +255,6 @@ static Ops ops(Object x){
return RATIO_OPS;
else if(xc == BigDecimal.class)
return BIGDECIMAL_OPS;
- else if(xc == double[].class)
- return DOUBLEARRAY_OPS;
- else if(xc == float[].class)
- return FLOATARRAY_OPS;
else
return INTEGER_OPS;
}