diff --git a/src/jvm/clojure/lang/BigInt.java b/src/jvm/clojure/lang/BigInt.java index 7cf441fa97..1732a76090 100644 --- a/src/jvm/clojure/lang/BigInt.java +++ b/src/jvm/clojure/lang/BigInt.java @@ -14,121 +14,96 @@ import java.math.BigInteger; -public class BigInt extends Number{ +public final class BigInt extends Number{ -final long lng; -final BigInteger bint; -static final BigInteger MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE); -static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE); +final public long lpart; +final public BigInteger bipart; -private BigInt(long lng, BigInteger bint){ - this.lng = lng; - this.bint = bint; +//must follow Long +public int hashCode(){ + if(bipart == null) + return (int) (this.lpart ^ (this.lpart >>> 32)); + return bipart.hashCode(); } -public BigInteger getBigInteger(){ - return bint; +public boolean equals(Object obj){ + if(this == obj) + return true; + if(obj instanceof BigInt) + { + BigInt o = (BigInt) obj; + if(bipart == null) + return o.bipart == null && this.lpart == o.lpart; + return o.bipart != null && this.bipart.equals(o.bipart); + } + return false; } -public long getLong(){ - return lng; +private BigInt(long lpart, BigInteger bipart){ + this.lpart = lpart; + this.bipart = bipart; } -public static BigInt fromBigInteger(BigInteger bint){ - if(MIN_LONG.compareTo(bint) <= 0 && MAX_LONG.compareTo(bint) >= 0) - return new BigInt(bint.longValue(), null); +public static BigInt fromBigInteger(BigInteger val){ + if(val.bitLength() < 64) + return new BigInt(val.longValue(), null); else - return new BigInt(0, bint); + return new BigInt(0, val); } -public static BigInt fromLong(long lng){ - return new BigInt(lng, null); +public static BigInt fromLong(long val){ + return new BigInt(val, null); } public BigInteger toBigInteger(){ - if(bint == null) - return BigInteger.valueOf(lng); + if(bipart == null) + return BigInteger.valueOf(lpart); else - return bint; + return bipart; } ///// java.lang.Number: public int intValue(){ - if(bint == null) - { - if(lng < Integer.MIN_VALUE) - return Integer.MIN_VALUE; - else if(lng > Integer.MAX_VALUE) - return Integer.MAX_VALUE; - else - return (int)lng; - } + if(bipart == null) + return (int) lpart; else - return bint.intValue(); + return bipart.intValue(); } public long longValue(){ - if(bint == null) - return lng; + if(bipart == null) + return lpart; else - return bint.longValue(); + return bipart.longValue(); } public float floatValue(){ - if(bint == null) - { - if(lng < Float.MIN_VALUE) - return Float.NEGATIVE_INFINITY; - else if(lng > Float.MAX_VALUE) - return Float.POSITIVE_INFINITY; - else - return lng; - } + if(bipart == null) + return lpart; else - return bint.floatValue(); + return bipart.floatValue(); } public double doubleValue(){ - if(bint == null) - { - if(lng < Double.MIN_VALUE) - return Double.NEGATIVE_INFINITY; - else if(lng > Double.MAX_VALUE) - return Double.POSITIVE_INFINITY; - else - return lng; - } + if(bipart == null) + return lpart; else - return bint.doubleValue(); + return bipart.doubleValue(); } public byte byteValue(){ - if(bint == null) - { - if(lng < Byte.MIN_VALUE) - return Byte.MIN_VALUE; - else if(lng > Byte.MAX_VALUE) - return Byte.MAX_VALUE; - else - return (byte)lng; - } + if(bipart == null) + return (byte) lpart; else - return bint.byteValue(); + return bipart.byteValue(); } public short shortValue(){ - if(bint == null) - { - if(lng < Short.MIN_VALUE) - return Short.MIN_VALUE; - else if(lng > Short.MAX_VALUE) - return Short.MAX_VALUE; - else - return (short)lng; - } + if(bipart == null) + return (short) lpart; else - return bint.shortValue(); + return bipart.shortValue(); } } diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java index aa04a814e8..f20530a01a 100644 --- a/src/jvm/clojure/lang/Numbers.java +++ b/src/jvm/clojure/lang/Numbers.java @@ -232,6 +232,11 @@ static public boolean equiv(Number x, Number y){ return ops(x).combine(ops(y)).equiv(x, y); } +static public boolean equal(Number x, Number y){ + return category(x) == category(y) + && ops(x).combine(ops(y)).equiv(x, y); +} + static public boolean lt(Object x, Object y){ return ops(x).combine(ops(y)).lt((Number)x, (Number)y); } @@ -1108,6 +1113,8 @@ public Number shiftRight(Number x, int n){ static final LongBitOps LONG_BITOPS = new LongBitOps(); static final BigIntegerBitOps BIGINTEGER_BITOPS = new BigIntegerBitOps(); +static public enum Category {INTEGER, FLOATING, DECIMAL, RATIO}; + static Ops ops(Object x){ Class xc = x.getClass(); @@ -1129,6 +1136,27 @@ else if(xc == BigDecimal.class) return LONG_OPS; } +static Category category(Object x){ + Class xc = x.getClass(); + + if(xc == Integer.class) + return Category.INTEGER; + else if(xc == Double.class) + return Category.FLOATING; + else if(xc == Long.class) + return Category.INTEGER; + else if(xc == Float.class) + return Category.FLOATING; + else if(xc == BigInteger.class) + return Category.INTEGER; + else if(xc == Ratio.class) + return Category.RATIO; + else if(xc == BigDecimal.class) + return Category.DECIMAL; + else + return Category.INTEGER; +} + static BitOps bitOps(Object x){ Class xc = x.getClass(); diff --git a/src/jvm/clojure/lang/PersistentArrayMap.java b/src/jvm/clojure/lang/PersistentArrayMap.java index 5cdfdead64..f2d3834811 100644 --- a/src/jvm/clojure/lang/PersistentArrayMap.java +++ b/src/jvm/clojure/lang/PersistentArrayMap.java @@ -198,9 +198,7 @@ private int indexOf(Object key){ } static boolean equalKey(Object k1, Object k2){ - if(k1 == null) - return k2 == null; - return k1.equals(k2); + return Util.equiv(k1, k2); } public Iterator iterator(){ diff --git a/src/jvm/clojure/lang/PersistentHashMap.java b/src/jvm/clojure/lang/PersistentHashMap.java index 935fab593a..b07076bc24 100644 --- a/src/jvm/clojure/lang/PersistentHashMap.java +++ b/src/jvm/clojure/lang/PersistentHashMap.java @@ -503,7 +503,7 @@ public INode assoc(int shift, int hash, Object key, Object val, Box addedLeaf){ return this; return new BitmapIndexedNode(null, bitmap, cloneAndSet(array, 2*idx+1, n)); } - if(Util.equals(key, keyOrNull)) { + if(Util.equiv(key, keyOrNull)) { if(val == valOrNode) return this; return new BitmapIndexedNode(null, bitmap, cloneAndSet(array, 2*idx+1, val)); @@ -558,7 +558,7 @@ public INode without(int shift, int hash, Object key){ return null; return new BitmapIndexedNode(null, bitmap ^ bit, removePair(array, idx)); } - if(Util.equals(key, keyOrNull)) + if(Util.equiv(key, keyOrNull)) // TODO: collapse return new BitmapIndexedNode(null, bitmap ^ bit, removePair(array, idx)); return this; @@ -573,7 +573,7 @@ public IMapEntry find(int shift, int hash, Object key){ Object valOrNode = array[2*idx+1]; if(keyOrNull == null) return ((INode) valOrNode).find(shift + 5, hash, key); - if(Util.equals(key, keyOrNull)) + if(Util.equiv(key, keyOrNull)) return new MapEntry(keyOrNull, valOrNode); return null; } @@ -587,7 +587,7 @@ public Object find(int shift, int hash, Object key, Object notFound){ Object valOrNode = array[2*idx+1]; if(keyOrNull == null) return ((INode) valOrNode).find(shift + 5, hash, key, notFound); - if(Util.equals(key, keyOrNull)) + if(Util.equiv(key, keyOrNull)) return valOrNode; return notFound; } @@ -641,7 +641,7 @@ public INode assoc(AtomicReference edit, int shift, int hash, Object key return this; return editAndSet(edit, 2*idx+1, n); } - if(Util.equals(key, keyOrNull)) { + if(Util.equiv(key, keyOrNull)) { if(val == valOrNode) return this; return editAndSet(edit, 2*idx+1, val); @@ -707,7 +707,7 @@ public INode without(AtomicReference edit, int shift, int hash, Object k removedLeaf.val = removedLeaf; return editAndRemovePair(edit, bit, idx); } - if(Util.equals(key, keyOrNull)) { + if(Util.equiv(key, keyOrNull)) { removedLeaf.val = removedLeaf; // TODO: collapse return editAndRemovePair(edit, bit, idx); @@ -763,7 +763,7 @@ public IMapEntry find(int shift, int hash, Object key){ int idx = findIndex(key); if(idx < 0) return null; - if(Util.equals(key, array[idx])) + if(Util.equiv(key, array[idx])) return new MapEntry(array[idx], array[idx+1]); return null; } @@ -772,7 +772,7 @@ public Object find(int shift, int hash, Object key, Object notFound){ int idx = findIndex(key); if(idx < 0) return notFound; - if(Util.equals(key, array[idx])) + if(Util.equiv(key, array[idx])) return array[idx+1]; return notFound; } @@ -784,7 +784,7 @@ public ISeq nodeSeq(){ public int findIndex(Object key){ for(int i = 0; i < 2*count; i+=2) { - if(Util.equals(key, array[i])) + if(Util.equiv(key, array[i])) return i; } return -1; diff --git a/src/jvm/clojure/lang/Util.java b/src/jvm/clojure/lang/Util.java index 4817dd56cb..3e80172ddb 100644 --- a/src/jvm/clojure/lang/Util.java +++ b/src/jvm/clojure/lang/Util.java @@ -21,7 +21,7 @@ static public boolean equiv(Object k1, Object k2){ if(k1 != null) { if(k1 instanceof Number && k2 instanceof Number) - return Numbers.equiv(k1, k2); + return Numbers.equal((Number)k1, (Number)k2); else if(k1 instanceof IPersistentCollection && k2 instanceof IPersistentCollection) return ((IPersistentCollection)k1).equiv(k2); return k1.equals(k2); @@ -35,7 +35,7 @@ static public boolean equals(Object k1, Object k2){ return k1 != null && k1.equals(k2); } -//* +/* static public boolean equals(long x, long y){ return x == y; } @@ -44,21 +44,21 @@ static public boolean equals(double x, double y){ return x == y; } -static public boolean equals(long x, Object y){ - return equals(Numbers.num(x),y); -} - -static public boolean equals(Object x, long y){ - return equals(x,Numbers.num(y)); -} - -static public boolean equals(double x, Object y){ - return equals((Double)x,y); -} - -static public boolean equals(Object x, double y){ - return equals(x,(Double)y); -} +//static public boolean equals(long x, Object y){ +// return equals(Numbers.num(x),y); +//} +// +//static public boolean equals(Object x, long y){ +// return equals(x,Numbers.num(y)); +//} +// +//static public boolean equals(double x, Object y){ +// return equals((Double)x,y); +//} +// +//static public boolean equals(Object x, double y){ +// return equals(x,(Double)y); +//} static public boolean equiv(long x, long y){ return x == y; @@ -68,21 +68,21 @@ static public boolean equiv(double x, double y){ return x == y; } -static public boolean equiv(long x, Object y){ - return equiv(Numbers.num(x),y); -} - -static public boolean equiv(Object x, long y){ - return equiv(x,Numbers.num(y)); -} - -static public boolean equiv(double x, Object y){ - return equiv((Double)x,y); -} - -static public boolean equiv(Object x, double y){ - return equiv(x,(Double)y); -} +//static public boolean equiv(long x, Object y){ +// return equiv(Numbers.num(x),y); +//} +// +//static public boolean equiv(Object x, long y){ +// return equiv(x,Numbers.num(y)); +//} +// +//static public boolean equiv(double x, Object y){ +// return equiv((Double)x,y); +//} +// +//static public boolean equiv(Object x, double y){ +// return equiv(x,(Double)y); +//} //*/ static public boolean identical(Object k1, Object k2){