summaryrefslogtreecommitdiff
path: root/src/jvm/clojure/lang/Numbers.java
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2008-04-11 14:59:15 +0000
committerRich Hickey <richhickey@gmail.com>2008-04-11 14:59:15 +0000
commit039cc991390f9213192998c39828d0f60247c8d0 (patch)
treef72657d74166533456619ee1daf25e56be56d33f /src/jvm/clojure/lang/Numbers.java
parent914c26752481ffd380b5e4f8e7754a7a68d27adc (diff)
bitops in Numbers, from Stephen C. Gilardi
Diffstat (limited to 'src/jvm/clojure/lang/Numbers.java')
-rw-r--r--src/jvm/clojure/lang/Numbers.java610
1 files changed, 528 insertions, 82 deletions
diff --git a/src/jvm/clojure/lang/Numbers.java b/src/jvm/clojure/lang/Numbers.java
index 1cf95bb4..fc315ac9 100644
--- a/src/jvm/clojure/lang/Numbers.java
+++ b/src/jvm/clojure/lang/Numbers.java
@@ -20,37 +20,87 @@ public class Numbers{
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 boolean isZero(Number x);
+
public boolean isPos(Number x);
+
public boolean isNeg(Number x);
public Number add(Number x, Number y);
+
public Number multiply(Number x, Number y);
+
public Number divide(Number x, Number y);
+
public Number quotient(Number x, Number y);
+
public Number remainder(Number x, Number y);
public boolean equiv(Number x, Number y);
+
public boolean lt(Number x, Number y);
public Number negate(Number x);
+
public Number inc(Number x);
+
public Number dec(Number x);
}
+static interface BitOps{
+ BitOps combine(BitOps y);
+
+ BitOps bitOpsWith(IntegerBitOps x);
+
+ BitOps bitOpsWith(LongBitOps x);
+
+ BitOps bitOpsWith(BigIntegerBitOps x);
+
+ public Number not(Number x);
+
+ public Number and(Number x, Number y);
+
+ public Number or(Number x, Number y);
+
+ public Number xor(Number x, Number y);
+
+ public Number andNot(Number x, Number y);
+
+ public Number clearBit(Number x, int n);
+
+ public Number setBit(Number x, int n);
+
+ public Number flipBit(Number x, int n);
+
+ public boolean testBit(Number x, int n);
+
+ public Number shiftLeft(Number x, int n);
+
+ public Number shiftRight(Number x, int n);
+}
+
+
static public boolean isZero(Number x){
return ops(x).isZero(x);
}
+
static public boolean isPos(Number x){
return ops(x).isPos(x);
}
+
static public boolean isNeg(Number x){
return ops(x).isNeg(x);
}
@@ -58,11 +108,13 @@ static public boolean isNeg(Number x){
static public Number negate(Number x){
return ops(x).negate(x);
}
+
static public Number inc(Number x){
return ops(x).inc(x);
}
+
static public Number dec(Number x){
- return ops(x).dec(x);
+ return ops(x).dec(x);
}
static public Number add(Number x, Number y){
@@ -126,8 +178,8 @@ static Number remainder(double n, double d){
static public boolean equiv(Object x, Object y){
return y instanceof Number && x instanceof Number
- && equiv((Number) x, (Number) y);
- }
+ && equiv((Number) x, (Number) y);
+}
static public boolean equiv(Number x, Number y){
return ops(x).combine(ops(y)).equiv(x, y);
@@ -151,9 +203,9 @@ static public boolean gte(Number x, Number y){
static public int compare(Number x, Number y){
Ops ops = ops(x).combine(ops(y));
- if(ops.lt(x,y))
+ if(ops.lt(x, y))
return -1;
- else if(ops.lt(y,x))
+ else if(ops.lt(y, x))
return 1;
return 0;
}
@@ -183,9 +235,9 @@ static Ratio toRatio(Object x){
BigInteger bv = bx.unscaledValue();
int scale = bx.scale();
if(scale < 0)
- return new Ratio(bv.multiply(BigInteger.TEN.pow(-scale)),BigInteger.ONE);
+ return new Ratio(bv.multiply(BigInteger.TEN.pow(-scale)), BigInteger.ONE);
else
- return new Ratio(bv,BigInteger.TEN.pow(scale));
+ return new Ratio(bv, BigInteger.TEN.pow(scale));
}
return new Ratio(toBigInteger(x), BigInteger.ONE);
}
@@ -209,6 +261,15 @@ static public Number rationalize(Number 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 Number reduce(long val){
+ if(val >= Integer.MIN_VALUE && val <= Integer.MAX_VALUE)
+ return (int) val;
else
return val;
}
@@ -227,18 +288,88 @@ static public Number divide(BigInteger n, BigInteger d){
(d.signum() < 0 ? d.negate() : d));
}
+static public Number not(Number x){
+ return bitOps(x).not(x);
+}
+
+
+static public Number and(Number x, Number y){
+ return bitOps(x).combine(bitOps(y)).and(x, y);
+}
+
+static public Number or(Number x, Number y){
+ return bitOps(x).combine(bitOps(y)).or(x, y);
+}
+
+static public Number xor(Number x, Number y){
+ return bitOps(x).combine(bitOps(y)).xor(x, y);
+}
+
+static public Number andNot(Number x, Number y){
+ return bitOps(x).combine(bitOps(y)).andNot(x, y);
+}
+
+static public Number clearBit(Number x, int n){
+ if(n < 0)
+ throw new ArithmeticException("Negative bit index");
+ return bitOps(x).clearBit(x, n);
+}
+
+static public Number setBit(Number x, int n){
+ if(n < 0)
+ throw new ArithmeticException("Negative bit index");
+ return bitOps(x).setBit(x, n);
+}
+
+static public Number flipBit(Number x, int n){
+ if(n < 0)
+ throw new ArithmeticException("Negative bit index");
+ return bitOps(x).flipBit(x, n);
+}
+
+static public boolean testBit(Number x, int n){
+ if(n < 0)
+ throw new ArithmeticException("Negative bit index");
+ return bitOps(x).testBit(x, n);
+}
+
+static public Number shiftLeft(Number x, int n){
+ return bitOps(x).shiftLeft(x, n);
+}
+
+static public Number shiftRight(Number x, int n){
+ return bitOps(x).shiftRight(x, n);
+}
+
final static class IntegerOps implements Ops{
public Ops combine(Ops y){
return y.opsWith(this);
}
- final public Ops opsWith(IntegerOps x){return this;}
- final public Ops opsWith(FloatOps x){return FLOAT_OPS;}
- final public Ops opsWith(DoubleOps x){return DOUBLE_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(IntegerOps x){
+ return this;
+ }
+
+ final public Ops opsWith(FloatOps x){
+ return FLOAT_OPS;
+ }
+
+ final public Ops opsWith(DoubleOps x){
+ return DOUBLE_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;
+ }
public boolean isZero(Number x){
return x.intValue() == 0;
@@ -255,14 +386,14 @@ final static class IntegerOps implements Ops{
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 (int) ret;
return ret;
}
final public Number multiply(Number x, Number y){
long ret = x.longValue() * y.longValue();
if(ret <= Integer.MAX_VALUE && ret >= Integer.MIN_VALUE)
- return (int)ret;
+ return (int) ret;
return ret;
}
@@ -319,15 +450,15 @@ final static class IntegerOps implements Ops{
public Number inc(Number x){
int val = x.intValue();
if(val < Integer.MAX_VALUE)
- return val+1;
- return BigInteger.valueOf((long)val + 1);
+ return val + 1;
+ return BigInteger.valueOf((long) val + 1);
}
public Number dec(Number x){
int val = x.intValue();
if(val > Integer.MIN_VALUE)
- return val-1;
- return BigInteger.valueOf((long)val - 1);
+ return val - 1;
+ return BigInteger.valueOf((long) val - 1);
}
}
@@ -336,12 +467,29 @@ final static class FloatOps implements Ops{
return y.opsWith(this);
}
- final public Ops opsWith(IntegerOps x){return this;}
- final public Ops opsWith(FloatOps x){return this;}
- final public Ops opsWith(DoubleOps x){return DOUBLE_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(IntegerOps x){
+ return this;
+ }
+
+ final public Ops opsWith(FloatOps x){
+ return this;
+ }
+
+ final public Ops opsWith(DoubleOps x){
+ return DOUBLE_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;
+ }
public boolean isZero(Number x){
return x.floatValue() == 0;
@@ -402,12 +550,29 @@ final static class DoubleOps implements Ops{
return y.opsWith(this);
}
- final public Ops opsWith(IntegerOps x){return this;}
- final public Ops opsWith(FloatOps x){return this;}
- final public Ops opsWith(DoubleOps x){return this;}
- 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(IntegerOps x){
+ return this;
+ }
+
+ final public Ops opsWith(FloatOps x){
+ return this;
+ }
+
+ final public Ops opsWith(DoubleOps x){
+ return this;
+ }
+
+ final public Ops opsWith(RatioOps x){
+ return this;
+ }
+
+ final public Ops opsWith(BigIntegerOps x){
+ return this;
+ }
+
+ final public Ops opsWith(BigDecimalOps x){
+ return this;
+ }
public boolean isZero(Number x){
return x.doubleValue() == 0;
@@ -440,7 +605,7 @@ final static class DoubleOps implements Ops{
public Number remainder(Number x, Number y){
return Numbers.remainder(x.doubleValue(), y.doubleValue());
}
-
+
public boolean equiv(Number x, Number y){
return x.doubleValue() == y.doubleValue();
}
@@ -468,12 +633,29 @@ final static class RatioOps implements Ops{
return y.opsWith(this);
}
- final public Ops opsWith(IntegerOps x){return this;}
- final public Ops opsWith(FloatOps x){return FLOAT_OPS;}
- final public Ops opsWith(DoubleOps x){return DOUBLE_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(IntegerOps x){
+ return this;
+ }
+
+ final public Ops opsWith(FloatOps x){
+ return FLOAT_OPS;
+ }
+
+ final public Ops opsWith(DoubleOps x){
+ return DOUBLE_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;
+ }
public boolean isZero(Number x){
Ratio r = (Ratio) x;
@@ -502,21 +684,21 @@ final static class RatioOps implements Ops{
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
return Numbers.divide(ry.numerator.multiply(rx.numerator)
- , ry.denominator.multiply(rx.denominator));
+ , ry.denominator.multiply(rx.denominator));
}
public Number divide(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
return Numbers.divide(ry.denominator.multiply(rx.numerator)
- , ry.numerator.multiply(rx.denominator));
+ , ry.numerator.multiply(rx.denominator));
}
public Number quotient(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
BigInteger q = rx.numerator.multiply(ry.denominator).divide(
- rx.denominator.multiply(ry.numerator));
+ rx.denominator.multiply(ry.numerator));
return reduce(q);
}
@@ -524,7 +706,7 @@ final static class RatioOps implements Ops{
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
BigInteger q = rx.numerator.multiply(ry.denominator).divide(
- rx.denominator.multiply(ry.numerator));
+ rx.denominator.multiply(ry.numerator));
return Numbers.subtract(x, Numbers.multiply(q, y));
}
@@ -538,7 +720,7 @@ final static class RatioOps implements Ops{
public boolean lt(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
- return Numbers.lt(rx.numerator.multiply(ry.denominator),ry.numerator.multiply(rx.denominator));
+ return Numbers.lt(rx.numerator.multiply(ry.denominator), ry.numerator.multiply(rx.denominator));
}
//public Number subtract(Number x, Number y);
@@ -548,11 +730,11 @@ final static class RatioOps implements Ops{
}
public Number inc(Number x){
- return Numbers.add(x,1);
+ return Numbers.add(x, 1);
}
public Number dec(Number x){
- return Numbers.add(x,-1);
+ return Numbers.add(x, -1);
}
}
@@ -562,12 +744,29 @@ final static class BigIntegerOps implements Ops{
return y.opsWith(this);
}
- final public Ops opsWith(IntegerOps x){return this;}
- final public Ops opsWith(FloatOps x){return FLOAT_OPS;}
- final public Ops opsWith(DoubleOps x){return DOUBLE_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(IntegerOps x){
+ return this;
+ }
+
+ final public Ops opsWith(FloatOps x){
+ return FLOAT_OPS;
+ }
+
+ final public Ops opsWith(DoubleOps x){
+ return DOUBLE_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;
+ }
public boolean isZero(Number x){
BigInteger bx = toBigInteger(x);
@@ -630,17 +829,34 @@ final static class BigIntegerOps implements Ops{
final static class BigDecimalOps implements Ops{
final static Var MATH_CONTEXT = RT.MATH_CONTEXT;
-
+
public Ops combine(Ops y){
return y.opsWith(this);
}
- final public Ops opsWith(IntegerOps x){return this;}
- final public Ops opsWith(FloatOps x){return FLOAT_OPS;}
- final public Ops opsWith(DoubleOps x){return DOUBLE_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(IntegerOps x){
+ return this;
+ }
+
+ final public Ops opsWith(FloatOps x){
+ return FLOAT_OPS;
+ }
+
+ final public Ops opsWith(DoubleOps x){
+ return DOUBLE_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;
+ }
public boolean isZero(Number x){
BigDecimal bx = (BigDecimal) x;
@@ -659,37 +875,37 @@ final static class BigDecimalOps implements Ops{
final public Number add(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.get();
- return mc == null
- ? toBigDecimal(x).add(toBigDecimal(y))
- : toBigDecimal(x).add(toBigDecimal(y), mc);
+ return mc == null
+ ? toBigDecimal(x).add(toBigDecimal(y))
+ : toBigDecimal(x).add(toBigDecimal(y), mc);
}
final public Number multiply(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.get();
- return mc == null
- ? toBigDecimal(x).multiply(toBigDecimal(y))
- : toBigDecimal(x).multiply(toBigDecimal(y), mc);
+ return mc == null
+ ? toBigDecimal(x).multiply(toBigDecimal(y))
+ : toBigDecimal(x).multiply(toBigDecimal(y), mc);
}
public Number divide(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.get();
- return mc == null
- ? toBigDecimal(x).divide(toBigDecimal(y))
- : toBigDecimal(x).divide(toBigDecimal(y), mc);
+ return mc == null
+ ? toBigDecimal(x).divide(toBigDecimal(y))
+ : toBigDecimal(x).divide(toBigDecimal(y), mc);
}
public Number quotient(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.get();
- return mc == null
- ? toBigDecimal(x).divideToIntegralValue(toBigDecimal(y))
- : toBigDecimal(x).divideToIntegralValue(toBigDecimal(y), mc);
+ return mc == null
+ ? toBigDecimal(x).divideToIntegralValue(toBigDecimal(y))
+ : toBigDecimal(x).divideToIntegralValue(toBigDecimal(y), mc);
}
public Number remainder(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.get();
- return mc == null
- ? toBigDecimal(x).remainder(toBigDecimal(y))
- : toBigDecimal(x).remainder(toBigDecimal(y), mc);
+ return mc == null
+ ? toBigDecimal(x).remainder(toBigDecimal(y))
+ : toBigDecimal(x).remainder(toBigDecimal(y), mc);
}
public boolean equiv(Number x, Number y){
@@ -703,25 +919,236 @@ final static class BigDecimalOps implements Ops{
//public Number subtract(Number x, Number y);
final public Number negate(Number x){
MathContext mc = (MathContext) MATH_CONTEXT.get();
- return mc == null
- ? ((BigDecimal)x).negate()
- : ((BigDecimal)x).negate(mc);
+ return mc == null
+ ? ((BigDecimal) x).negate()
+ : ((BigDecimal) x).negate(mc);
}
public Number inc(Number x){
MathContext mc = (MathContext) MATH_CONTEXT.get();
BigDecimal bx = (BigDecimal) x;
- return mc == null
- ? bx.add(BigDecimal.ONE)
- : bx.add(BigDecimal.ONE, mc);
+ return mc == null
+ ? bx.add(BigDecimal.ONE)
+ : bx.add(BigDecimal.ONE, mc);
}
public Number dec(Number x){
MathContext mc = (MathContext) MATH_CONTEXT.get();
BigDecimal bx = (BigDecimal) x;
- return mc == null
- ? bx.subtract(BigDecimal.ONE)
- : bx.subtract(BigDecimal.ONE, mc);
+ return mc == null
+ ? bx.subtract(BigDecimal.ONE)
+ : bx.subtract(BigDecimal.ONE, mc);
+ }
+}
+
+final static class IntegerBitOps implements BitOps{
+ public BitOps combine(BitOps y){
+ return y.bitOpsWith(this);
+ }
+
+ final public BitOps bitOpsWith(IntegerBitOps x){
+ return this;
+ }
+
+ final public BitOps bitOpsWith(LongBitOps x){
+ return LONG_BITOPS;
+ }
+
+ final public BitOps bitOpsWith(BigIntegerBitOps x){
+ return BIGINTEGER_BITOPS;
+ }
+
+
+ public Number not(Number x){
+ return ~x.intValue();
+ }
+
+ public Number and(Number x, Number y){
+ return x.intValue() & y.intValue();
+ }
+
+ public Number or(Number x, Number y){
+ return x.intValue() | y.intValue();
+ }
+
+ public Number xor(Number x, Number y){
+ return x.intValue() ^ y.intValue();
+ }
+
+ public Number andNot(Number x, Number y){
+ return x.intValue() & ~y.intValue();
+ }
+
+ public Number clearBit(Number x, int n){
+ if(n < 32)
+ return x.intValue() & ~(1 << n);
+ throw new ArithmeticException("bit index out of range");
+ }
+
+ public Number setBit(Number x, int n){
+ if(n < 32)
+ return x.intValue() | (1 << n);
+ throw new ArithmeticException("bit index out of range");
+ }
+
+ public Number flipBit(Number x, int n){
+ if(n < 32)
+ return x.intValue() ^ (1 << n);
+ throw new ArithmeticException("bit index out of range");
+ }
+
+ public boolean testBit(Number x, int n){
+ if(n < 32)
+ return (x.intValue() & (1 << n)) != 0;
+ throw new ArithmeticException("bit index out of range");
+ }
+
+ public Number shiftLeft(Number x, int n){
+ if(n < 0)
+ return shiftRight(x, -n);
+ return x.intValue() << n;
+ }
+
+ public Number shiftRight(Number x, int n){
+ if(n < 0)
+ return shiftLeft(x, -n);
+ return x.intValue() >> n;
+ }
+}
+
+final static class LongBitOps implements BitOps{
+ public BitOps combine(BitOps y){
+ return y.bitOpsWith(this);
+ }
+
+ final public BitOps bitOpsWith(IntegerBitOps x){
+ return this;
+ }
+
+ final public BitOps bitOpsWith(LongBitOps x){
+ return this;
+ }
+
+ final public BitOps bitOpsWith(BigIntegerBitOps x){
+ return BIGINTEGER_BITOPS;
+ }
+
+ public Number not(Number x){
+ return ~x.longValue();
+ }
+
+ public Number and(Number x, Number y){
+ return x.longValue() & y.longValue();
+ }
+
+ public Number or(Number x, Number y){
+ return x.longValue() | y.longValue();
+ }
+
+ public Number xor(Number x, Number y){
+ return x.longValue() ^ y.longValue();
+ }
+
+ public Number andNot(Number x, Number y){
+ return x.longValue() & ~y.longValue();
+ }
+
+ public Number clearBit(Number x, int n){
+ if(n < 64)
+ return x.longValue() & ~(1L << n);
+ throw new ArithmeticException("bit index out of range");
+ }
+
+ public Number setBit(Number x, int n){
+ if(n < 64)
+ return x.longValue() | (1L << n);
+ throw new ArithmeticException("bit index out of range");
+ }
+
+ public Number flipBit(Number x, int n){
+ if(n < 64)
+ return x.longValue() ^ (1L << n);
+ throw new ArithmeticException("bit index out of range");
+ }
+
+ public boolean testBit(Number x, int n){
+ if(n < 64)
+ return (x.longValue() & (1L << n)) != 0;
+ throw new ArithmeticException("bit index out of range");
+ }
+
+ public Number shiftLeft(Number x, int n){
+ if(n < 0)
+ return shiftRight(x, -n);
+ return x.longValue() << n;
+ }
+
+ public Number shiftRight(Number x, int n){
+ if(n < 0)
+ return shiftLeft(x, -n);
+ return x.longValue() >> n;
+ }
+}
+
+final static class BigIntegerBitOps implements BitOps{
+ public BitOps combine(BitOps y){
+ return y.bitOpsWith(this);
+ }
+
+ final public BitOps bitOpsWith(IntegerBitOps x){
+ return this;
+ }
+
+ final public BitOps bitOpsWith(LongBitOps x){
+ return this;
+ }
+
+ final public BitOps bitOpsWith(BigIntegerBitOps x){
+ return this;
+ }
+
+ public Number not(Number x){
+ return toBigInteger(x).not();
+ }
+
+ public Number and(Number x, Number y){
+ return toBigInteger(x).and(toBigInteger(y));
+ }
+
+ public Number or(Number x, Number y){
+ return toBigInteger(x).or(toBigInteger(y));
+ }
+
+ public Number xor(Number x, Number y){
+ return toBigInteger(x).xor(toBigInteger(y));
+ }
+
+ public Number andNot(Number x, Number y){
+ return toBigInteger(x).andNot(toBigInteger(y));
+ }
+
+ public Number clearBit(Number x, int n){
+ return toBigInteger(x).clearBit(n);
+ }
+
+ public Number setBit(Number x, int n){
+ return toBigInteger(x).setBit(n);
+ }
+
+ public Number flipBit(Number x, int n){
+ return toBigInteger(x).flipBit(n);
+ }
+
+ public boolean testBit(Number x, int n){
+ return toBigInteger(x).testBit(n);
+ }
+
+ public Number shiftLeft(Number x, int n){
+ return toBigInteger(x).shiftLeft(n);
+ }
+
+ public Number shiftRight(Number x, int n){
+ return toBigInteger(x).shiftRight(n);
}
}
@@ -732,6 +1159,10 @@ static final RatioOps RATIO_OPS = new RatioOps();
static final BigIntegerOps BIGINTEGER_OPS = new BigIntegerOps();
static final BigDecimalOps BIGDECIMAL_OPS = new BigDecimalOps();
+static final IntegerBitOps INTEGER_BITOPS = new IntegerBitOps();
+static final LongBitOps LONG_BITOPS = new LongBitOps();
+static final BigIntegerBitOps BIGINTEGER_BITOPS = new BigIntegerBitOps();
+
static Ops ops(Object x){
Class xc = x.getClass();
@@ -753,4 +1184,19 @@ static Ops ops(Object x){
return INTEGER_OPS;
}
+static BitOps bitOps(Object x){
+ Class xc = x.getClass();
+
+ if(xc == Integer.class)
+ return INTEGER_BITOPS;
+ else if(xc == Long.class)
+ return LONG_BITOPS;
+ else if(xc == BigInteger.class)
+ return BIGINTEGER_BITOPS;
+ else if(xc == Double.class || xc == Float.class || xc == BigDecimalOps.class || xc == Ratio.class)
+ throw new ArithmeticException("bit operation on non integer type: " + xc);
+ else
+ return INTEGER_BITOPS;
+}
+
}