Source for gnu.java.math.GMP

   1: /* gnu.java.math.GMP -- Arbitary precision integers using GMP
   2:    Copyright (C) 2006 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package gnu.java.math;
  40: 
  41: import gnu.classpath.Pointer;
  42: 
  43: /**
  44:  * Implement BigInteger using GMP
  45:  */
  46: public final class GMP
  47: {
  48:   private Pointer native_ptr;
  49:   private int refCount = 1;
  50: 
  51:   public GMP()
  52:   {
  53:     super();
  54: 
  55:     natInitialize();
  56:   }
  57: 
  58:   private synchronized void acquireRef()
  59:   {
  60:     refCount++;
  61:   }
  62: 
  63:   private synchronized void releaseRef()
  64:   {
  65:     refCount--;
  66:     if (refCount == 0)
  67:       {
  68:         natFinalize();
  69:         native_ptr = null;
  70:       }
  71:   }
  72: 
  73:   protected void finalize()
  74:   {
  75:     releaseRef();
  76:   }
  77: 
  78: 
  79:   public void fromByteArray(byte[] v)
  80:   {
  81:     acquireRef();
  82:     natFromByteArray(v);
  83:     releaseRef();
  84:   }
  85: 
  86:   public void fromBI(GMP x)
  87:   {
  88:     acquireRef();
  89:     x.acquireRef();
  90:     natFromBI(x.native_ptr);
  91:     x.releaseRef();
  92:     releaseRef();
  93:   }
  94: 
  95:   public void fromLong(long n)
  96:   {
  97:     acquireRef();
  98:     natFromLong(n);
  99:     releaseRef();
 100:   }
 101: 
 102:   public int fromString(String s, int rdx)
 103:   {
 104:     acquireRef();
 105:     int result = natFromString(s, rdx);
 106:     releaseRef();
 107:     return result;
 108:   }
 109: 
 110:   public void fromSignedMagnitude(byte[] m, boolean isNegative)
 111:   {
 112:     acquireRef();
 113:     natFromSignedMagnitude(m, isNegative);
 114:     releaseRef();
 115:   }
 116: 
 117:   public String toString(int b)
 118:   {
 119:     acquireRef();
 120:     String result = natToString(b);
 121:     releaseRef();
 122:     return result;
 123:   }
 124: 
 125:   public void toByteArray(byte[] r)
 126:   {
 127:     acquireRef();
 128:     natToByteArray(r);
 129:     releaseRef();
 130:   }
 131: 
 132:   public double doubleValue()
 133:   {
 134:     acquireRef();
 135:     double result = natDoubleValue();
 136:     releaseRef();
 137:     return result;
 138:   }
 139: 
 140:   public int absIntValue()
 141:   {
 142:     acquireRef();
 143:     int result = natAbsIntValue();
 144:     releaseRef();
 145:     return result;
 146:   }
 147: 
 148:   public int compare(GMP x)
 149:   {
 150:     acquireRef();
 151:     x.acquireRef();
 152:     int result = natCompare(x.native_ptr);
 153:     x.releaseRef();
 154:     releaseRef();
 155:     return result;
 156:   }
 157: 
 158:   public void add(GMP x, GMP r)
 159:   {
 160:     acquireRef();
 161:     x.acquireRef();
 162:     r.acquireRef();
 163:     natAdd(x.native_ptr, r.native_ptr);
 164:     r.releaseRef();
 165:     x.releaseRef();
 166:     releaseRef();
 167:   }
 168: 
 169:   public void subtract(GMP x, GMP r)
 170:   {
 171:     acquireRef();
 172:     x.acquireRef();
 173:     r.acquireRef();
 174:     natSubtract(x.native_ptr, r.native_ptr);
 175:     r.releaseRef();
 176:     x.releaseRef();
 177:     releaseRef();
 178:   }
 179: 
 180:   public void multiply(GMP x, GMP r)
 181:   {
 182:     acquireRef();
 183:     x.acquireRef();
 184:     r.acquireRef();
 185:     natMultiply(x.native_ptr, r.native_ptr);
 186:     r.releaseRef();
 187:     x.releaseRef();
 188:     releaseRef();
 189:   }
 190: 
 191:   public void quotient(GMP x, GMP r)
 192:   {
 193:     acquireRef();
 194:     x.acquireRef();
 195:     r.acquireRef();
 196:     natQuotient(x.native_ptr, r.native_ptr);
 197:     r.releaseRef();
 198:     x.releaseRef();
 199:     releaseRef();
 200:   }
 201: 
 202:   public void remainder(GMP x, GMP r)
 203:   {
 204:     acquireRef();
 205:     x.acquireRef();
 206:     r.acquireRef();
 207:     natRemainder(x.native_ptr, r.native_ptr);
 208:     r.releaseRef();
 209:     x.releaseRef();
 210:     releaseRef();
 211:   }
 212: 
 213:   public void quotientAndRemainder(GMP x, GMP q, GMP r)
 214:   {
 215:     acquireRef();
 216:     x.acquireRef();
 217:     q.acquireRef();
 218:     r.acquireRef();
 219:     natQuotientAndRemainder(x.native_ptr, q.native_ptr, r.native_ptr);
 220:     r.releaseRef();
 221:     q.releaseRef();
 222:     x.releaseRef();
 223:     releaseRef();
 224:   }
 225: 
 226:   public void modulo(GMP x, GMP r)
 227:   {
 228:     acquireRef();
 229:     x.acquireRef();
 230:     r.acquireRef();
 231:     natModulo(x.native_ptr, r.native_ptr);
 232:     r.releaseRef();
 233:     x.releaseRef();
 234:     releaseRef();
 235:   }
 236: 
 237:   public void pow(int n, GMP r)
 238:   {
 239:     acquireRef();
 240:     r.acquireRef();
 241:     natPow(n, r.native_ptr);
 242:     r.releaseRef();
 243:     releaseRef();
 244:   }
 245: 
 246:   public void modPow(GMP e, GMP m, GMP r)
 247:   {
 248:     acquireRef();
 249:     e.acquireRef();
 250:     m.acquireRef();
 251:     r.acquireRef();
 252:     natModPow(e.native_ptr, m.native_ptr, r.native_ptr);
 253:     r.releaseRef();
 254:     m.releaseRef();
 255:     e.releaseRef();
 256:     releaseRef();
 257:   }
 258: 
 259:   public void modInverse(GMP m, GMP r)
 260:   {
 261:     acquireRef();
 262:     m.acquireRef();
 263:     r.acquireRef();
 264:     natModInverse(m.native_ptr, r.native_ptr);
 265:     r.releaseRef();
 266:     m.releaseRef();
 267:     releaseRef();
 268:   }
 269: 
 270:   public void gcd(GMP x, GMP r)
 271:   {
 272:     acquireRef();
 273:     x.acquireRef();
 274:     r.acquireRef();
 275:     natGCD(x.native_ptr, r.native_ptr);
 276:     r.releaseRef();
 277:     x.releaseRef();
 278:     releaseRef();
 279:   }
 280: 
 281:   public void shiftLeft(int n, GMP r)
 282:   {
 283:     acquireRef();
 284:     r.acquireRef();
 285:     natShiftLeft(n, r.native_ptr);
 286:     r.releaseRef();
 287:     releaseRef();
 288:   }
 289: 
 290:   public void shiftRight(int n, GMP r)
 291:   {
 292:     acquireRef();
 293:     r.acquireRef();
 294:     natShiftRight(n, r.native_ptr);
 295:     r.releaseRef();
 296:     releaseRef();
 297:   }
 298: 
 299:   public void abs(GMP r)
 300:   {
 301:     acquireRef();
 302:     r.acquireRef();
 303:     natAbs(r.native_ptr);
 304:     r.releaseRef();
 305:     releaseRef();
 306:   }
 307: 
 308:   public void negate(GMP r)
 309:   {
 310:     acquireRef();
 311:     r.acquireRef();
 312:     natNegate(r.native_ptr);
 313:     r.releaseRef();
 314:     releaseRef();
 315:   }
 316: 
 317:   public int bitLength()
 318:   {
 319:     acquireRef();
 320:     int result = natBitLength();
 321:     releaseRef();
 322:     return result;
 323:   }
 324: 
 325:   public int bitCount()
 326:   {
 327:     acquireRef();
 328:     int result = natSetBitCount();
 329:     releaseRef();
 330:     return result;
 331:   }
 332: 
 333:   public void and(GMP x, GMP r)
 334:   {
 335:     acquireRef();
 336:     x.acquireRef();
 337:     r.acquireRef();
 338:     natAnd(x.native_ptr, r.native_ptr);
 339:     r.releaseRef();
 340:     x.releaseRef();
 341:     releaseRef();
 342:   }
 343: 
 344:   public void or(GMP x, GMP r)
 345:   {
 346:     acquireRef();
 347:     x.acquireRef();
 348:     r.acquireRef();
 349:     natOr(x.native_ptr, r.native_ptr);
 350:     r.releaseRef();
 351:     x.releaseRef();
 352:     releaseRef();
 353:   }
 354: 
 355:   public void xor(GMP x, GMP r)
 356:   {
 357:     acquireRef();
 358:     x.acquireRef();
 359:     r.acquireRef();
 360:     natXor(x.native_ptr, r.native_ptr);
 361:     r.releaseRef();
 362:     x.releaseRef();
 363:     releaseRef();
 364:   }
 365: 
 366:   public void andNot(GMP x, GMP r)
 367:   {
 368:     acquireRef();
 369:     x.acquireRef();
 370:     r.acquireRef();
 371:     natAndNot(x.native_ptr, r.native_ptr);
 372:     r.releaseRef();
 373:     x.releaseRef();
 374:     releaseRef();
 375:   }
 376: 
 377:   public void not(GMP r)
 378:   {
 379:     acquireRef();
 380:     r.acquireRef();
 381:     natNot(r.native_ptr);
 382:     r.releaseRef();
 383:     releaseRef();
 384:   }
 385: 
 386:   public void flipBit(int n, GMP r)
 387:   {
 388:     acquireRef();
 389:     r.acquireRef();
 390:     natFlipBit(n, r.native_ptr);
 391:     r.releaseRef();
 392:     releaseRef();
 393:   }
 394: 
 395:   public int testBit(int n)
 396:   {
 397:     acquireRef();
 398:     int result = natTestBit(n);
 399:     releaseRef();
 400:     return result;
 401:   }
 402: 
 403:   public void setBit(int n, boolean setIt, GMP r)
 404:   {
 405:     acquireRef();
 406:     r.acquireRef();
 407:     natSetBit(n, setIt, r.native_ptr);
 408:     r.releaseRef();
 409:     releaseRef();
 410:   }
 411: 
 412:   public int testPrimality(int certainty)
 413:   {
 414:     acquireRef();
 415:     int result = natTestPrimality(certainty);
 416:     releaseRef();
 417:     return result;
 418:   }
 419: 
 420:   public int lowestSetBit()
 421:   {
 422:     acquireRef();
 423:     int result = natLowestSetBit();
 424:     releaseRef();
 425:     return result;
 426:   }
 427: 
 428:   // Native methods .........................................................
 429: 
 430:   public static native void natInitializeLibrary();
 431: 
 432:   private native void natInitialize();
 433:   private native void natFinalize();
 434: 
 435:   private native void natFromLong(long n);
 436:   private native void natFromBI(Pointer x);
 437:   private native void natFromByteArray(byte[] v);
 438:   private native int natFromString(String s, int rdx);
 439:   private native void natFromSignedMagnitude(byte[] m, boolean isNegative);
 440: 
 441:   private native String natToString(int base);
 442:   private native void natToByteArray(byte[] r);
 443:   private native int natAbsIntValue();
 444:   private native double natDoubleValue();
 445: 
 446:   private native int natCompare(Pointer y);
 447:   private native void natAdd(Pointer x, Pointer r);
 448:   private native void natSubtract(Pointer x, Pointer r);
 449:   private native void natMultiply(Pointer x, Pointer r);
 450:   private native void natQuotient(Pointer x, Pointer r);
 451:   private native void natRemainder(Pointer x, Pointer r);
 452:   private native void natQuotientAndRemainder(Pointer x, Pointer q, Pointer r);
 453:   private native void natModulo(Pointer m, Pointer r);
 454:   private native void natPow(int n, Pointer r);
 455:   private native void natModPow(Pointer e, Pointer m, Pointer r);
 456:   private native void natModInverse(Pointer x, Pointer r);
 457:   private native void natGCD(Pointer x, Pointer r);
 458:   private native int natTestPrimality(int c);
 459:   private native void natShiftLeft(int n, Pointer r);
 460:   private native void natShiftRight(int n, Pointer r);
 461:   private native int natLowestSetBit();
 462:   private native void natAbs(Pointer r);
 463:   private native void natNegate(Pointer r);
 464:   private native int natBitLength();
 465:   private native int natSetBitCount();
 466:   private native void natXor(Pointer x, Pointer r);
 467:   private native void natOr(Pointer x, Pointer r);
 468:   private native void natAnd(Pointer x, Pointer r);
 469:   private native void natAndNot(Pointer x, Pointer r);
 470:   private native void natFlipBit(int n, Pointer r);
 471:   private native int natTestBit(int n);
 472:   private native void natSetBit(int n, boolean setIt, Pointer r);
 473:   private native void natNot(Pointer r);
 474: }