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


