diff options
author | Rich Hickey <richhickey@gmail.com> | 2008-04-14 01:17:34 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2008-04-14 01:17:34 +0000 |
commit | 51859f1b6f67bf10174b4008251ac5ed5428e0e6 (patch) | |
tree | a7103d93b40c5a40a72897b2feebbf034660afd2 /src/jvm/clojure/lang/Numbers.java | |
parent | d5c487f85c6ef98911d4175729d1df56f86fac7e (diff) |
arbitrary precision bitops
Diffstat (limited to 'src/jvm/clojure/lang/Numbers.java')
-rw-r--r-- | src/jvm/clojure/lang/Numbers.java | 69 |
1 files changed, 45 insertions, 24 deletions
diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java index fc315ac9..b849a081 100644 --- a/src/jvm/clojure/lang/Numbers.java +++ b/src/jvm/clojure/lang/Numbers.java @@ -980,37 +980,54 @@ final static class IntegerBitOps implements BitOps{ } public Number clearBit(Number x, int n){ - if(n < 32) + if (n < 31) return x.intValue() & ~(1 << n); - throw new ArithmeticException("bit index out of range"); + else if (n < 63) + return x.longValue() & ~(1L << n); + else + return toBigInteger(x).clearBit(n); } public Number setBit(Number x, int n){ - if(n < 32) + if (n < 31) return x.intValue() | (1 << n); - throw new ArithmeticException("bit index out of range"); + else if (n < 63) + return x.longValue() | (1L << n); + else + return toBigInteger(x).setBit(n); } public Number flipBit(Number x, int n){ - if(n < 32) + if (n < 31) return x.intValue() ^ (1 << n); - throw new ArithmeticException("bit index out of range"); + else if (n < 63) + return x.longValue() ^ (1L << n); + else + return toBigInteger(x).flipBit(n); } public boolean testBit(Number x, int n){ - if(n < 32) + if (n < 32) return (x.intValue() & (1 << n)) != 0; - throw new ArithmeticException("bit index out of range"); + else if (n < 64) + return (x.longValue() & (1L << n)) != 0; + else + return toBigInteger(x).testBit(n); } public Number shiftLeft(Number x, int n){ - if(n < 0) - return shiftRight(x, -n); - return x.intValue() << n; + if (n < 32) + { + if (n < 0) + return shiftRight(x, -n); + return reduce(x.longValue() << n); + } + else + return reduce(toBigInteger(x).shiftLeft(n)); } - + public Number shiftRight(Number x, int n){ - if(n < 0) + if (n < 0) return shiftLeft(x, -n); return x.intValue() >> n; } @@ -1054,37 +1071,41 @@ final static class LongBitOps implements BitOps{ } public Number clearBit(Number x, int n){ - if(n < 64) + if (n < 63) return x.longValue() & ~(1L << n); - throw new ArithmeticException("bit index out of range"); + else + return toBigInteger(x).clearBit(n); } public Number setBit(Number x, int n){ - if(n < 64) + if (n < 63) return x.longValue() | (1L << n); - throw new ArithmeticException("bit index out of range"); + else + return toBigInteger(x).setBit(n); } public Number flipBit(Number x, int n){ - if(n < 64) + if (n < 63) return x.longValue() ^ (1L << n); - throw new ArithmeticException("bit index out of range"); + else + return toBigInteger(x).flipBit(n); } public boolean testBit(Number x, int n){ - if(n < 64) + if (n < 64) return (x.longValue() & (1L << n)) != 0; - throw new ArithmeticException("bit index out of range"); + else + return toBigInteger(x).testBit(n); } public Number shiftLeft(Number x, int n){ - if(n < 0) + if (n < 0) return shiftRight(x, -n); - return x.longValue() << n; + return reduce(toBigInteger(x).shiftLeft(n)); } public Number shiftRight(Number x, int n){ - if(n < 0) + if (n < 0) return shiftLeft(x, -n); return x.longValue() >> n; } |