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 GMP()51 public GMP() 52 { 53 super(); 54 55 natInitialize(); 56 } 57 acquireRef()58 private synchronized void acquireRef() 59 { 60 refCount++; 61 } 62 releaseRef()63 private synchronized void releaseRef() 64 { 65 refCount--; 66 if (refCount == 0) 67 { 68 natFinalize(); 69 native_ptr = null; 70 } 71 } 72 finalize()73 protected void finalize() 74 { 75 releaseRef(); 76 } 77 78 fromByteArray(byte[] v)79 public void fromByteArray(byte[] v) 80 { 81 acquireRef(); 82 natFromByteArray(v); 83 releaseRef(); 84 } 85 fromBI(GMP x)86 public void fromBI(GMP x) 87 { 88 acquireRef(); 89 x.acquireRef(); 90 natFromBI(x.native_ptr); 91 x.releaseRef(); 92 releaseRef(); 93 } 94 fromLong(long n)95 public void fromLong(long n) 96 { 97 acquireRef(); 98 natFromLong(n); 99 releaseRef(); 100 } 101 fromString(String s, int rdx)102 public int fromString(String s, int rdx) 103 { 104 acquireRef(); 105 int result = natFromString(s, rdx); 106 releaseRef(); 107 return result; 108 } 109 fromSignedMagnitude(byte[] m, boolean isNegative)110 public void fromSignedMagnitude(byte[] m, boolean isNegative) 111 { 112 acquireRef(); 113 natFromSignedMagnitude(m, isNegative); 114 releaseRef(); 115 } 116 toString(int b)117 public String toString(int b) 118 { 119 acquireRef(); 120 String result = natToString(b); 121 releaseRef(); 122 return result; 123 } 124 toByteArray(byte[] r)125 public void toByteArray(byte[] r) 126 { 127 acquireRef(); 128 natToByteArray(r); 129 releaseRef(); 130 } 131 doubleValue()132 public double doubleValue() 133 { 134 acquireRef(); 135 double result = natDoubleValue(); 136 releaseRef(); 137 return result; 138 } 139 absIntValue()140 public int absIntValue() 141 { 142 acquireRef(); 143 int result = natAbsIntValue(); 144 releaseRef(); 145 return result; 146 } 147 compare(GMP x)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 add(GMP x, GMP r)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 subtract(GMP x, GMP r)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 multiply(GMP x, GMP r)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 quotient(GMP x, GMP r)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 remainder(GMP x, GMP r)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 quotientAndRemainder(GMP x, GMP q, GMP r)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 modulo(GMP x, GMP r)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 pow(int n, GMP r)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 modPow(GMP e, GMP m, GMP r)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 modInverse(GMP m, GMP r)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 gcd(GMP x, GMP r)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 shiftLeft(int n, GMP r)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 shiftRight(int n, GMP r)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 abs(GMP r)299 public void abs(GMP r) 300 { 301 acquireRef(); 302 r.acquireRef(); 303 natAbs(r.native_ptr); 304 r.releaseRef(); 305 releaseRef(); 306 } 307 negate(GMP r)308 public void negate(GMP r) 309 { 310 acquireRef(); 311 r.acquireRef(); 312 natNegate(r.native_ptr); 313 r.releaseRef(); 314 releaseRef(); 315 } 316 bitLength()317 public int bitLength() 318 { 319 acquireRef(); 320 int result = natBitLength(); 321 releaseRef(); 322 return result; 323 } 324 bitCount()325 public int bitCount() 326 { 327 acquireRef(); 328 int result = natSetBitCount(); 329 releaseRef(); 330 return result; 331 } 332 and(GMP x, GMP r)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 or(GMP x, GMP r)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 xor(GMP x, GMP r)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 andNot(GMP x, GMP r)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 not(GMP r)377 public void not(GMP r) 378 { 379 acquireRef(); 380 r.acquireRef(); 381 natNot(r.native_ptr); 382 r.releaseRef(); 383 releaseRef(); 384 } 385 flipBit(int n, GMP r)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 testBit(int n)395 public int testBit(int n) 396 { 397 acquireRef(); 398 int result = natTestBit(n); 399 releaseRef(); 400 return result; 401 } 402 setBit(int n, boolean setIt, GMP r)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 testPrimality(int certainty)412 public int testPrimality(int certainty) 413 { 414 acquireRef(); 415 int result = natTestPrimality(certainty); 416 releaseRef(); 417 return result; 418 } 419 lowestSetBit()420 public int lowestSetBit() 421 { 422 acquireRef(); 423 int result = natLowestSetBit(); 424 releaseRef(); 425 return result; 426 } 427 428 // Native methods ......................................................... 429 natInitializeLibrary()430 public static native void natInitializeLibrary(); 431 natInitialize()432 private native void natInitialize(); natFinalize()433 private native void natFinalize(); 434 natFromLong(long n)435 private native void natFromLong(long n); natFromBI(Pointer x)436 private native void natFromBI(Pointer x); natFromByteArray(byte[] v)437 private native void natFromByteArray(byte[] v); natFromString(String s, int rdx)438 private native int natFromString(String s, int rdx); natFromSignedMagnitude(byte[] m, boolean isNegative)439 private native void natFromSignedMagnitude(byte[] m, boolean isNegative); 440 natToString(int base)441 private native String natToString(int base); natToByteArray(byte[] r)442 private native void natToByteArray(byte[] r); natAbsIntValue()443 private native int natAbsIntValue(); natDoubleValue()444 private native double natDoubleValue(); 445 natCompare(Pointer y)446 private native int natCompare(Pointer y); natAdd(Pointer x, Pointer r)447 private native void natAdd(Pointer x, Pointer r); natSubtract(Pointer x, Pointer r)448 private native void natSubtract(Pointer x, Pointer r); natMultiply(Pointer x, Pointer r)449 private native void natMultiply(Pointer x, Pointer r); natQuotient(Pointer x, Pointer r)450 private native void natQuotient(Pointer x, Pointer r); natRemainder(Pointer x, Pointer r)451 private native void natRemainder(Pointer x, Pointer r); natQuotientAndRemainder(Pointer x, Pointer q, Pointer r)452 private native void natQuotientAndRemainder(Pointer x, Pointer q, Pointer r); natModulo(Pointer m, Pointer r)453 private native void natModulo(Pointer m, Pointer r); natPow(int n, Pointer r)454 private native void natPow(int n, Pointer r); natModPow(Pointer e, Pointer m, Pointer r)455 private native void natModPow(Pointer e, Pointer m, Pointer r); natModInverse(Pointer x, Pointer r)456 private native void natModInverse(Pointer x, Pointer r); natGCD(Pointer x, Pointer r)457 private native void natGCD(Pointer x, Pointer r); natTestPrimality(int c)458 private native int natTestPrimality(int c); natShiftLeft(int n, Pointer r)459 private native void natShiftLeft(int n, Pointer r); natShiftRight(int n, Pointer r)460 private native void natShiftRight(int n, Pointer r); natLowestSetBit()461 private native int natLowestSetBit(); natAbs(Pointer r)462 private native void natAbs(Pointer r); natNegate(Pointer r)463 private native void natNegate(Pointer r); natBitLength()464 private native int natBitLength(); natSetBitCount()465 private native int natSetBitCount(); natXor(Pointer x, Pointer r)466 private native void natXor(Pointer x, Pointer r); natOr(Pointer x, Pointer r)467 private native void natOr(Pointer x, Pointer r); natAnd(Pointer x, Pointer r)468 private native void natAnd(Pointer x, Pointer r); natAndNot(Pointer x, Pointer r)469 private native void natAndNot(Pointer x, Pointer r); natFlipBit(int n, Pointer r)470 private native void natFlipBit(int n, Pointer r); natTestBit(int n)471 private native int natTestBit(int n); natSetBit(int n, boolean setIt, Pointer r)472 private native void natSetBit(int n, boolean setIt, Pointer r); natNot(Pointer r)473 private native void natNot(Pointer r); 474 } 475