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