Artifact 98ad32571378dbff81ed8f9ac0e3d4d9575c38fcee74c5b48dbf52e231792e4d:
- Executable file
r37/lisp/csl/jlisp/LispBigInteger.java
— part of check-in
[f2fda60abd]
at
2011-09-02 18:13:33
on branch master
— Some historical releases purely for archival purposes
git-svn-id: https://svn.code.sf.net/p/reduce-algebra/code/trunk/historical@1375 2bfe0521-f11c-4a00-b80e-6202646ff360 (user: arthurcnorman@users.sourceforge.net, size: 16183) [annotate] [blame] [check-ins using] [more...]
// // This file is part of the Jlisp implementation of Standard Lisp // Copyright \u00a9 (C) Codemist Ltd, 1998-2000. // import java.math.*; import java.io.*; import java.util.*; class LispBigInteger extends LispInteger { BigInteger value; LispBigInteger(int value) { this.value = BigInteger.valueOf((long)value); } LispBigInteger(long value) { this.value = BigInteger.valueOf(value); } LispBigInteger(BigInteger value) { this.value = value; } int intValue() throws Exception { int n; if (value.bitLength() <= 31 && (n = value.intValue()) <= 0x3fffffff && n >= -0x40000000) return n; Jlisp.error("Integer is too large", this); return 0; // never reached } BigInteger bigIntValue() { return value; } LispObject eval() { return this; } String printAs() { if ((currentFlags & (printBinary | printOctal | printHex)) == 0) return value.toString(); else if ((currentFlags & printBinary) != 0) return value.toString(2); else if ((currentFlags & printOctal) != 0) return value.toString(8); else // if ((currentFlags & printHex) != 0) return value.toString(16); } void iprint() { String s = printAs(); if ((currentFlags & noLineBreak) == 0 && currentOutput.column + s.length() > currentOutput.lineLength) currentOutput.println(); currentOutput.print(s); } void blankprint() { String s = printAs(); if ((currentFlags & noLineBreak) == 0 && currentOutput.column + s.length() >= currentOutput.lineLength) currentOutput.println(); else currentOutput.print(" "); currentOutput.print(s); } double doubleValue() { return value.doubleValue(); } public boolean lispequals(Object b) { if (!(b instanceof LispBigInteger)) return false; return value.compareTo(((LispBigInteger)b).value) == 0; } public boolean equals(Object b) { if (!(b instanceof LispBigInteger)) return false; return value.compareTo(((LispBigInteger)b).value) == 0; } public int lisphashCode() { return value.hashCode(); } public int hashCode() { return value.hashCode(); } void scan() { if (Jlisp.objects.contains(value)) // seen before? { if (!Jlisp.repeatedObjects.containsKey(value)) { Jlisp.repeatedObjects.put( value, Jlisp.nil); // value is junk at this stage } } else Jlisp.objects.add(value); } void dump() throws IOException { Object w = Jlisp.repeatedObjects.get(value); if (w != null && w instanceof Integer) putSharedRef(w); // processed before else { if (w != null) // will be used again sometime { Jlisp.repeatedObjects.put( value, new Integer(Jlisp.sharedIndex++)); Jlisp.odump.write(X_STORE); } // Now this is the first time I see this integer while writing a dump // file. I will put out a byte that says "here comes an integer", then // the number of bytes used to represent it, and finally the set of bytes // concerned. To save a little space I have variants to cope with the // various possible sizes of length-code needed. byte [] rep = value.toByteArray(); int length = rep.length; putPrefix2(length, X_INTn, X_INT); for (int i=0; i<length; i++) Jlisp.odump.write(rep[i]); } } public LispObject negate() throws Exception { return valueOf(value.negate()); } public LispObject abs() throws Exception { if (value.signum() >= 0) return this; else return valueOf(value.negate()); } public LispObject msd() throws Exception { return valueOf(value.bitLength()); } public LispObject lsd() throws Exception { return valueOf(value.getLowestSetBit()); } public LispObject not() throws Exception { return valueOf(value.not()); } public LispObject reduceMod() throws Exception { return valueOf(value.mod(Jlisp.bigModulus)); } public LispObject add1() throws Exception { return valueOf(value.add(BigInteger.ONE)); } public LispObject sub1() throws Exception { return valueOf(value.subtract(BigInteger.ONE)); } public LispObject floor() throws Exception { return this; } public LispObject ceiling() throws Exception { return this; } public LispObject round() throws Exception { return this; } public LispObject truncate() throws Exception { return this; } public LispObject ash(int n) throws Exception { if (n > 0) return valueOf(value.shiftLeft(n)); else if (n < 0) return valueOf(value.shiftRight(-n)); else return this; } public LispObject ash1(int n) throws Exception { if (n > 0) return valueOf(value.shiftLeft(n)); else if (n < 0) { if (value.signum() >= 0) return valueOf(value.shiftRight(-n)); else return valueOf(value.negate().shiftRight(-n).negate()); } else return this; } public LispObject rightshift(int n) throws Exception { return valueOf(value.shiftRight(n)); } public LispObject evenp() throws Exception { return value.testBit(0) ? Jlisp.nil : Jlisp.lispTrue; } public LispObject oddp() throws Exception { return value.testBit(0) ? Jlisp.lispTrue : Jlisp.nil; } public LispObject fix() throws Exception { return this; } public LispObject fixp() throws Exception { return Jlisp.lispTrue; } public LispObject integerp() throws Exception { return Jlisp.lispTrue; } public LispObject jfloat() throws Exception { return new LispFloat(value.doubleValue()); } public LispObject floatp() throws Exception { return Jlisp.nil; } public LispObject minusp() throws Exception { return value.signum() < 0 ? Jlisp.lispTrue : Jlisp.nil; } public LispObject plusp() throws Exception { return value.signum() >= 0 ? Jlisp.lispTrue : Jlisp.nil; } public LispObject zerop() throws Exception { return value.signum() == 0 ? Jlisp.lispTrue : Jlisp.nil; } public LispObject onep() throws Exception { return (value.compareTo(BigInteger.ONE) == 0) ? Jlisp.lispTrue : Jlisp.nil; } public LispObject add(LispObject a) throws Exception { return a.addInteger(this); } public LispObject subtract(LispObject a) throws Exception { return a.subtractInteger(this); } public LispObject multiply(LispObject a) throws Exception { return a.multiplyInteger(this); } public LispObject expt(LispObject a) throws Exception { return a.exptInteger(this); } public LispObject divide(LispObject a) throws Exception { return a.divideInteger(this); } public LispObject remainder(LispObject a) throws Exception { return a.remainderInteger(this); } public LispObject quotientAndRemainder(LispObject a) throws Exception { return a.quotientAndRemainderInteger(this); } public LispObject mod(LispObject a) throws Exception { return a.modInteger(this); } public LispObject max(LispObject a) throws Exception { return a.maxInteger(this); } public LispObject min(LispObject a) throws Exception { return a.minInteger(this); } public LispObject and(LispObject a) throws Exception { return a.andInteger(this); } public LispObject or(LispObject a) throws Exception { return a.orInteger(this); } public LispObject xor(LispObject a) throws Exception { return a.xorInteger(this); } public LispObject gcd(LispObject a) throws Exception { return a.gcdInteger(this); } boolean eqn(LispObject a) throws Exception { return a.eqnInteger(this); } boolean neqn(LispObject a) throws Exception { return a.neqnInteger(this); } boolean ge(LispObject a) throws Exception { return a.geInteger(this); } boolean geq(LispObject a) throws Exception { return a.geqInteger(this); } boolean le(LispObject a) throws Exception { return a.leInteger(this); } boolean leq(LispObject a) throws Exception { return a.leqInteger(this); } // now versions that know they have 2 integer args public LispObject addInteger(LispBigInteger a) throws Exception { return valueOf(a.value.add(value)); } public LispObject subtractInteger(LispBigInteger a) throws Exception { return valueOf(a.value.subtract(value)); } public LispObject multiplyInteger(LispBigInteger a) throws Exception { return valueOf(a.value.multiply(value)); } public LispObject divideInteger(LispBigInteger a) throws Exception { return valueOf(a.value.divide(value)); } public LispObject remainderInteger(LispBigInteger a) throws Exception { return valueOf(a.value.remainder(value)); } public LispObject quotientAndRemainderInteger(LispBigInteger a) throws Exception { BigInteger [] r = a.value.divideAndRemainder(value); return new Cons(valueOf(r[0]), valueOf(r[1])); } public LispObject modInteger(LispBigInteger a) throws Exception { return valueOf(a.value.mod(value)); } public LispObject exptInteger(LispBigInteger a) throws Exception { switch (value.signum()) { case -1: return valueOf(0); case 0: return valueOf(1); default: if (value.bitLength() > 15) return Jlisp.error("integer result would be too large"); else return valueOf(a.value.pow(value.intValue())); } } public LispObject maxInteger(LispBigInteger a) throws Exception { if (a.value.compareTo(value) >= 0) return a; else return this; } public LispObject minInteger(LispBigInteger a) throws Exception { if (a.value.compareTo(value) <= 0) return a; else return this; } public LispObject andInteger(LispBigInteger a) throws Exception { return valueOf(a.value.and(value)); } public LispObject orInteger(LispBigInteger a) throws Exception { return valueOf(a.value.or(value)); } public LispObject xorInteger(LispBigInteger a) throws Exception { return valueOf(a.value.xor(value)); } public LispObject gcdInteger(LispBigInteger a) throws Exception { return valueOf(a.value.gcd(value)); } public boolean eqnInteger(LispBigInteger a) throws Exception { return (a.value.compareTo(value) == 0); } public boolean neqnInteger(LispBigInteger a) throws Exception { return (a.value.compareTo(value) != 0); } public boolean geInteger(LispBigInteger a) throws Exception { return (a.value.compareTo(value) > 0); } public boolean geqInteger(LispBigInteger a) throws Exception { return (a.value.compareTo(value) >= 0); } public boolean leInteger(LispBigInteger a) throws Exception { return (a.value.compareTo(value) < 0); } public boolean leqInteger(LispBigInteger a) throws Exception { return (a.value.compareTo(value) <= 0); } // Finally versions that mix big and small integers. I will generally cope by // converting the small integer to a big one. LispObject addSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).add(value)); } LispObject subtractSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).subtract(value)); } LispObject multiplySmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).multiply(value)); } LispObject divideSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).divide(value)); } LispObject remainderSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).remainder(value)); } LispObject quotientAndRemainderSmallInteger(LispSmallInteger a) throws Exception { BigInteger [] r = BigInteger.valueOf((long)a.value).divideAndRemainder(value); return new Cons(valueOf(r[0]), valueOf(r[1])); } LispObject modSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).mod(value)); } LispObject exptSmallInteger(LispSmallInteger a) throws Exception { switch (value.signum()) { case -1: return valueOf(0); case 0: return valueOf(1); default: if (value.bitLength() > 15) return Jlisp.error("integer result would be too large"); else return valueOf(BigInteger.valueOf((long)a.value).pow(value.intValue())); } } LispObject maxSmallInteger(LispSmallInteger a) throws Exception { if (BigInteger.valueOf((long)a.value).compareTo(value) >= 0) return a; else return this; } LispObject minSmallInteger(LispSmallInteger a) throws Exception { if (BigInteger.valueOf((long)a.value).compareTo(value) <= 0) return a; else return this; } LispObject andSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).and(value)); } LispObject orSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).or(value)); } LispObject xorSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).xor(value)); } LispObject gcdSmallInteger(LispSmallInteger a) throws Exception { return valueOf(BigInteger.valueOf((long)a.value).gcd(value)); } boolean eqnSmallInteger(LispSmallInteger a) throws Exception { return (BigInteger.valueOf((long)a.value).compareTo(value) == 0); } boolean neqnSmallInteger(LispSmallInteger a) throws Exception { return (BigInteger.valueOf((long)a.value).compareTo(value) != 0); } boolean geSmallInteger(LispSmallInteger a) throws Exception { return (BigInteger.valueOf((long)a.value).compareTo(value) > 0); } boolean geqSmallInteger(LispSmallInteger a) throws Exception { return (BigInteger.valueOf((long)a.value).compareTo(value) >= 0); } boolean leSmallInteger(LispSmallInteger a) throws Exception { return (BigInteger.valueOf((long)a.value).compareTo(value) < 0); } boolean leqSmallInteger(LispSmallInteger a) throws Exception { return (BigInteger.valueOf((long)a.value).compareTo(value) <= 0); } } // End of LispBigInteger.java