Extended-Precision Native Integers for Java by Lou Grinzo Listing One // mInt library copyright (c) 1997 Lou Grinzo import java.lang.System; class mIntError extends Exception { private int last_error; mIntError(int le) { last_error = le; }; int GetLastError() { return last_error; } } class mInt { private static final int num_components = 8; private int the_int[] = new int[num_components]; private static int last_error = 0; public static final int mInt_OK = 0; public static final int mInt_overflow = 1; public static final int mInt_underflow = 2; public static final int mInt_divide_by_zero = 3; public static final int mInt_invalid_char = 4; // Load the native methods and cache fieldIDs for last_error and the_int static { System.loadLibrary("mInt"); cacheFID(); } static private native void cacheFID(); // Constructors of various flavors ////////////////////// // See the called Set* methods for more details mInt(int x0, int x1, int x2, int x3, int x4, int x5, int x6, int x7) { Set(x0,x1,x2,x3,x4,x5,x6,x7); } mInt(int x) { SetFromInt32(x); } mInt(mInt x) { SetFrommInt(x); } mInt(String s) { SetFromString(s); } // Accessors and converters ///////////////////////////// public int[] GetInts() { int[] x = new int[num_components]; System.arraycopy(the_int,0,x,0,num_components); return x; } // Treat the ints as hex components of a huge signed integer public void Set(int x0, int x1, int x2, int x3, int x4, int x5, int x6, int x7) { the_int[0] = x0; the_int[1] = x1; the_int[2] = x2; the_int[3] = x3; the_int[4] = x4; the_int[5] = x5; the_int[6] = x6; the_int[7] = x7; } // Set the low-order int32 and sign-extend public void SetFromInt32(int x) { the_int[num_components - 1] = x; int temp = 0; if(x < 0) temp = -1; for(int i = 0; i < num_components - 1; i++) the_int[i] = temp; } // Simply copy the entire the_int array public void SetFrommInt(mInt x) { System.arraycopy(x.the_int,0,the_int,0,num_components); } public native int SetFromString(String s); public native String HexString(); public native String toString(); // Math methods ///////////////////////////////////////// public void Abs() { if(the_int[0] < 0) Negate(); } public native boolean Add(mInt y); public boolean AddInt32(int x) { return Add(new mInt(x)); } // Demos non-cached field access public native boolean testAdd(mInt y); // Demos object creation public native mInt test2Add(mInt y); // Wrap the primitive Add() to use exception public void test3Add(mInt y) throws mIntError { if(!Add(y)) throw new mIntError(GetAndClearLastError()); } public native boolean Subtract(mInt y); public boolean SubtractInt32(int x) { return Subtract(new mInt(x)); } public native boolean Multiply(mInt y); public boolean MultiplyInt32(int x) { return Multiply(new mInt(x)); } public native boolean Divide(mInt y); public boolean DivideInt32(int x) { return Divide(new mInt(x)); } public native boolean Remainder(mInt y); public boolean RemainderInt32(int x) { return Remainder(new mInt(x)); } // Compare two mInts, returning -1, 0, or 1 if // this is <, ==, or > x, like common C usage public native int Comp(mInt x); public mInt Max(mInt x, mInt y) { if(x.Comp(y) >= 0) return new mInt(x); else return new mInt(y); } public mInt Min(mInt x, mInt y) { if(x.Comp(y) <= 0) return new mInt(x); else return new mInt(y); } // Bit twiddlers //////////////////////////////////////// public native void Negate(); public native boolean ShiftLeft(); public native void ShiftRight(); public void AND(mInt x) { for(int i = 0; i < num_components; i++) the_int[i] &= x.the_int[i]; } public void OR(mInt x) { for(int i = 0; i < num_components; i++) the_int[i] |= x.the_int[i]; } public void NOT() { for(int i = 0; i < num_components; i++) the_int[i] = ~the_int[i]; } public void XOR(mInt x) { for(int i = 0; i < num_components; i++) the_int[i] ^= x.the_int[i]; } // Error detection methods ////////////////////////////// int GetLastError() { return last_error; } int GetAndClearLastError() { int temp = last_error; last_error = mInt_OK; return temp; } int GetAndSetLastError(int x) { int temp = last_error; last_error = x; return temp; } void SetLastError(int new_last_error) { last_error = new_last_error; } } 4