source: trunk/gcc/libjava/gnu/java/math/MPN.java

Last change on this file was 2, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 20.4 KB
Line 
1/* gnu.java.math.MPN
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38// Included from Kawa 1.6.62 with permission of the author,
39// Per Bothner <per@bothner.com>.
40
41package gnu.java.math;
42
43/** This contains various low-level routines for unsigned bigints.
44 * The interfaces match the mpn interfaces in gmp,
45 * so it should be easy to replace them with fast native functions
46 * that are trivial wrappers around the mpn_ functions in gmp
47 * (at least on platforms that use 32-bit "limbs").
48 */
49
50public class MPN
51{
52 /** Add x[0:size-1] and y, and write the size least
53 * significant words of the result to dest.
54 * Return carry, either 0 or 1.
55 * All values are unsigned.
56 * This is basically the same as gmp's mpn_add_1. */
57 public static int add_1 (int[] dest, int[] x, int size, int y)
58 {
59 long carry = (long) y & 0xffffffffL;
60 for (int i = 0; i < size; i++)
61 {
62 carry += ((long) x[i] & 0xffffffffL);
63 dest[i] = (int) carry;
64 carry >>= 32;
65 }
66 return (int) carry;
67 }
68
69 /** Add x[0:len-1] and y[0:len-1] and write the len least
70 * significant words of the result to dest[0:len-1].
71 * All words are treated as unsigned.
72 * @return the carry, either 0 or 1
73 * This function is basically the same as gmp's mpn_add_n.
74 */
75 public static int add_n (int dest[], int[] x, int[] y, int len)
76 {
77 long carry = 0;
78 for (int i = 0; i < len; i++)
79 {
80 carry += ((long) x[i] & 0xffffffffL)
81 + ((long) y[i] & 0xffffffffL);
82 dest[i] = (int) carry;
83 carry >>>= 32;
84 }
85 return (int) carry;
86 }
87
88 /** Subtract Y[0:size-1] from X[0:size-1], and write
89 * the size least significant words of the result to dest[0:size-1].
90 * Return borrow, either 0 or 1.
91 * This is basically the same as gmp's mpn_sub_n function.
92 */
93
94 public static int sub_n (int[] dest, int[] X, int[] Y, int size)
95 {
96 int cy = 0;
97 for (int i = 0; i < size; i++)
98 {
99 int y = Y[i];
100 int x = X[i];
101 y += cy; /* add previous carry to subtrahend */
102 // Invert the high-order bit, because: (unsigned) X > (unsigned) Y
103 // iff: (int) (X^0x80000000) > (int) (Y^0x80000000).
104 cy = (y^0x80000000) < (cy^0x80000000) ? 1 : 0;
105 y = x - y;
106 cy += (y^0x80000000) > (x ^ 0x80000000) ? 1 : 0;
107 dest[i] = y;
108 }
109 return cy;
110 }
111
112 /** Multiply x[0:len-1] by y, and write the len least
113 * significant words of the product to dest[0:len-1].
114 * Return the most significant word of the product.
115 * All values are treated as if they were unsigned
116 * (i.e. masked with 0xffffffffL).
117 * OK if dest==x (not sure if this is guaranteed for mpn_mul_1).
118 * This function is basically the same as gmp's mpn_mul_1.
119 */
120
121 public static int mul_1 (int[] dest, int[] x, int len, int y)
122 {
123 long yword = (long) y & 0xffffffffL;
124 long carry = 0;
125 for (int j = 0; j < len; j++)
126 {
127 carry += ((long) x[j] & 0xffffffffL) * yword;
128 dest[j] = (int) carry;
129 carry >>>= 32;
130 }
131 return (int) carry;
132 }
133
134 /**
135 * Multiply x[0:xlen-1] and y[0:ylen-1], and
136 * write the result to dest[0:xlen+ylen-1].
137 * The destination has to have space for xlen+ylen words,
138 * even if the result might be one limb smaller.
139 * This function requires that xlen >= ylen.
140 * The destination must be distinct from either input operands.
141 * All operands are unsigned.
142 * This function is basically the same gmp's mpn_mul. */
143
144 public static void mul (int[] dest,
145 int[] x, int xlen,
146 int[] y, int ylen)
147 {
148 dest[xlen] = MPN.mul_1 (dest, x, xlen, y[0]);
149
150 for (int i = 1; i < ylen; i++)
151 {
152 long yword = (long) y[i] & 0xffffffffL;
153 long carry = 0;
154 for (int j = 0; j < xlen; j++)
155 {
156 carry += ((long) x[j] & 0xffffffffL) * yword
157 + ((long) dest[i+j] & 0xffffffffL);
158 dest[i+j] = (int) carry;
159 carry >>>= 32;
160 }
161 dest[i+xlen] = (int) carry;
162 }
163 }
164
165 /* Divide (unsigned long) N by (unsigned int) D.
166 * Returns (remainder << 32)+(unsigned int)(quotient).
167 * Assumes (unsigned int)(N>>32) < (unsigned int)D.
168 * Code transcribed from gmp-2.0's mpn_udiv_w_sdiv function.
169 */
170 public static long udiv_qrnnd (long N, int D)
171 {
172 long q, r;
173 long a1 = N >>> 32;
174 long a0 = N & 0xffffffffL;
175 if (D >= 0)
176 {
177 if (a1 < ((D - a1 - (a0 >>> 31)) & 0xffffffffL))
178 {
179 /* dividend, divisor, and quotient are nonnegative */
180 q = N / D;
181 r = N % D;
182 }
183 else
184 {
185 /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
186 long c = N - ((long) D << 31);
187 /* Divide (c1*2^32 + c0) by d */
188 q = c / D;
189 r = c % D;
190 /* Add 2^31 to quotient */
191 q += 1 << 31;
192 }
193 }
194 else
195 {
196 long b1 = D >>> 1; /* d/2, between 2^30 and 2^31 - 1 */
197 //long c1 = (a1 >> 1); /* A/2 */
198 //int c0 = (a1 << 31) + (a0 >> 1);
199 long c = N >>> 1;
200 if (a1 < b1 || (a1 >> 1) < b1)
201 {
202 if (a1 < b1)
203 {
204 q = c / b1;
205 r = c % b1;
206 }
207 else /* c1 < b1, so 2^31 <= (A/2)/b1 < 2^32 */
208 {
209 c = ~(c - (b1 << 32));
210 q = c / b1; /* (A/2) / (d/2) */
211 r = c % b1;
212 q = (~q) & 0xffffffffL; /* (A/2)/b1 */
213 r = (b1 - 1) - r; /* r < b1 => new r >= 0 */
214 }
215 r = 2 * r + (a0 & 1);
216 if ((D & 1) != 0)
217 {
218 if (r >= q) {
219 r = r - q;
220 } else if (q - r <= ((long) D & 0xffffffffL)) {
221 r = r - q + D;
222 q -= 1;
223 } else {
224 r = r - q + D + D;
225 q -= 2;
226 }
227 }
228 }
229 else /* Implies c1 = b1 */
230 { /* Hence a1 = d - 1 = 2*b1 - 1 */
231 if (a0 >= ((long)(-D) & 0xffffffffL))
232 {
233 q = -1;
234 r = a0 + D;
235 }
236 else
237 {
238 q = -2;
239 r = a0 + D + D;
240 }
241 }
242 }
243
244 return (r << 32) | (q & 0xFFFFFFFFl);
245 }
246
247 /** Divide divident[0:len-1] by (unsigned int)divisor.
248 * Write result into quotient[0:len-1.
249 * Return the one-word (unsigned) remainder.
250 * OK for quotient==dividend.
251 */
252
253 public static int divmod_1 (int[] quotient, int[] dividend,
254 int len, int divisor)
255 {
256 int i = len - 1;
257 long r = dividend[i];
258 if ((r & 0xffffffffL) >= ((long)divisor & 0xffffffffL))
259 r = 0;
260 else
261 {
262 quotient[i--] = 0;
263 r <<= 32;
264 }
265
266 for (; i >= 0; i--)
267 {
268 int n0 = dividend[i];
269 r = (r & ~0xffffffffL) | (n0 & 0xffffffffL);
270 r = udiv_qrnnd (r, divisor);
271 quotient[i] = (int) r;
272 }
273 return (int)(r >> 32);
274 }
275
276 /* Subtract x[0:len-1]*y from dest[offset:offset+len-1].
277 * All values are treated as if unsigned.
278 * @return the most significant word of
279 * the product, minus borrow-out from the subtraction.
280 */
281 public static int submul_1 (int[] dest, int offset, int[] x, int len, int y)
282 {
283 long yl = (long) y & 0xffffffffL;
284 int carry = 0;
285 int j = 0;
286 do
287 {
288 long prod = ((long) x[j] & 0xffffffffL) * yl;
289 int prod_low = (int) prod;
290 int prod_high = (int) (prod >> 32);
291 prod_low += carry;
292 // Invert the high-order bit, because: (unsigned) X > (unsigned) Y
293 // iff: (int) (X^0x80000000) > (int) (Y^0x80000000).
294 carry = ((prod_low ^ 0x80000000) < (carry ^ 0x80000000) ? 1 : 0)
295 + prod_high;
296 int x_j = dest[offset+j];
297 prod_low = x_j - prod_low;
298 if ((prod_low ^ 0x80000000) > (x_j ^ 0x80000000))
299 carry++;
300 dest[offset+j] = prod_low;
301 }
302 while (++j < len);
303 return carry;
304 }
305
306 /** Divide zds[0:nx] by y[0:ny-1].
307 * The remainder ends up in zds[0:ny-1].
308 * The quotient ends up in zds[ny:nx].
309 * Assumes: nx>ny.
310 * (int)y[ny-1] < 0 (i.e. most significant bit set)
311 */
312
313 public static void divide (int[] zds, int nx, int[] y, int ny)
314 {
315 // This is basically Knuth's formulation of the classical algorithm,
316 // but translated from in scm_divbigbig in Jaffar's SCM implementation.
317
318 // Correspondance with Knuth's notation:
319 // Knuth's u[0:m+n] == zds[nx:0].
320 // Knuth's v[1:n] == y[ny-1:0]
321 // Knuth's n == ny.
322 // Knuth's m == nx-ny.
323 // Our nx == Knuth's m+n.
324
325 // Could be re-implemented using gmp's mpn_divrem:
326 // zds[nx] = mpn_divrem (&zds[ny], 0, zds, nx, y, ny).
327
328 int j = nx;
329 do
330 { // loop over digits of quotient
331 // Knuth's j == our nx-j.
332 // Knuth's u[j:j+n] == our zds[j:j-ny].
333 int qhat; // treated as unsigned
334 if (zds[j]==y[ny-1])
335 qhat = -1; // 0xffffffff
336 else
337 {
338 long w = (((long)(zds[j])) << 32) + ((long)zds[j-1] & 0xffffffffL);
339 qhat = (int) udiv_qrnnd (w, y[ny-1]);
340 }
341 if (qhat != 0)
342 {
343 int borrow = submul_1 (zds, j - ny, y, ny, qhat);
344 int save = zds[j];
345 long num = ((long)save&0xffffffffL) - ((long)borrow&0xffffffffL);
346 while (num != 0)
347 {
348 qhat--;
349 long carry = 0;
350 for (int i = 0; i < ny; i++)
351 {
352 carry += ((long) zds[j-ny+i] & 0xffffffffL)
353 + ((long) y[i] & 0xffffffffL);
354 zds[j-ny+i] = (int) carry;
355 carry >>>= 32;
356 }
357 zds[j] += carry;
358 num = carry - 1;
359 }
360 }
361 zds[j] = qhat;
362 } while (--j >= ny);
363 }
364
365 /** Number of digits in the conversion base that always fits in a word.
366 * For example, for base 10 this is 9, since 10**9 is the
367 * largest number that fits into a words (assuming 32-bit words).
368 * This is the same as gmp's __mp_bases[radix].chars_per_limb.
369 * @param radix the base
370 * @return number of digits */
371 public static int chars_per_word (int radix)
372 {
373 if (radix < 10)
374 {
375 if (radix < 8)
376 {
377 if (radix <= 2)
378 return 32;
379 else if (radix == 3)
380 return 20;
381 else if (radix == 4)
382 return 16;
383 else
384 return 18 - radix;
385 }
386 else
387 return 10;
388 }
389 else if (radix < 12)
390 return 9;
391 else if (radix <= 16)
392 return 8;
393 else if (radix <= 23)
394 return 7;
395 else if (radix <= 40)
396 return 6;
397 // The following are conservative, but we don't care.
398 else if (radix <= 256)
399 return 4;
400 else
401 return 1;
402 }
403
404 /** Count the number of leading zero bits in an int. */
405 public static int count_leading_zeros (int i)
406 {
407 if (i == 0)
408 return 32;
409 int count = 0;
410 for (int k = 16; k > 0; k = k >> 1) {
411 int j = i >>> k;
412 if (j == 0)
413 count += k;
414 else
415 i = j;
416 }
417 return count;
418 }
419
420 public static int set_str (int dest[], byte[] str, int str_len, int base)
421 {
422 int size = 0;
423 if ((base & (base - 1)) == 0)
424 {
425 // The base is a power of 2. Read the input string from
426 // least to most significant character/digit. */
427
428 int next_bitpos = 0;
429 int bits_per_indigit = 0;
430 for (int i = base; (i >>= 1) != 0; ) bits_per_indigit++;
431 int res_digit = 0;
432
433 for (int i = str_len; --i >= 0; )
434 {
435 int inp_digit = str[i];
436 res_digit |= inp_digit << next_bitpos;
437 next_bitpos += bits_per_indigit;
438 if (next_bitpos >= 32)
439 {
440 dest[size++] = res_digit;
441 next_bitpos -= 32;
442 res_digit = inp_digit >> (bits_per_indigit - next_bitpos);
443 }
444 }
445
446 if (res_digit != 0)
447 dest[size++] = res_digit;
448 }
449 else
450 {
451 // General case. The base is not a power of 2.
452 int indigits_per_limb = MPN.chars_per_word (base);
453 int str_pos = 0;
454
455 while (str_pos < str_len)
456 {
457 int chunk = str_len - str_pos;
458 if (chunk > indigits_per_limb)
459 chunk = indigits_per_limb;
460 int res_digit = str[str_pos++];
461 int big_base = base;
462
463 while (--chunk > 0)
464 {
465 res_digit = res_digit * base + str[str_pos++];
466 big_base *= base;
467 }
468
469 int cy_limb;
470 if (size == 0)
471 cy_limb = res_digit;
472 else
473 {
474 cy_limb = MPN.mul_1 (dest, dest, size, big_base);
475 cy_limb += MPN.add_1 (dest, dest, size, res_digit);
476 }
477 if (cy_limb != 0)
478 dest[size++] = cy_limb;
479 }
480 }
481 return size;
482 }
483
484 /** Compare x[0:size-1] with y[0:size-1], treating them as unsigned integers.
485 * @result -1, 0, or 1 depending on if x<y, x==y, or x>y.
486 * This is basically the same as gmp's mpn_cmp function.
487 */
488 public static int cmp (int[] x, int[] y, int size)
489 {
490 while (--size >= 0)
491 {
492 int x_word = x[size];
493 int y_word = y[size];
494 if (x_word != y_word)
495 {
496 // Invert the high-order bit, because:
497 // (unsigned) X > (unsigned) Y iff
498 // (int) (X^0x80000000) > (int) (Y^0x80000000).
499 return (x_word ^ 0x80000000) > (y_word ^0x80000000) ? 1 : -1;
500 }
501 }
502 return 0;
503 }
504
505 /** Compare x[0:xlen-1] with y[0:ylen-1], treating them as unsigned integers.
506 * @result -1, 0, or 1 depending on if x<y, x==y, or x>y.
507 */
508 public static int cmp (int[] x, int xlen, int[] y, int ylen)
509 {
510 return xlen > ylen ? 1 : xlen < ylen ? -1 : cmp (x, y, xlen);
511 }
512
513 /* Shift x[x_start:x_start+len-1] count bits to the "right"
514 * (i.e. divide by 2**count).
515 * Store the len least significant words of the result at dest.
516 * The bits shifted out to the right are returned.
517 * OK if dest==x.
518 * Assumes: 0 < count < 32
519 */
520
521 public static int rshift (int[] dest, int[] x, int x_start,
522 int len, int count)
523 {
524 int count_2 = 32 - count;
525 int low_word = x[x_start];
526 int retval = low_word << count_2;
527 int i = 1;
528 for (; i < len; i++)
529 {
530 int high_word = x[x_start+i];
531 dest[i-1] = (low_word >>> count) | (high_word << count_2);
532 low_word = high_word;
533 }
534 dest[i-1] = low_word >>> count;
535 return retval;
536 }
537
538 /* Shift x[x_start:x_start+len-1] count bits to the "right"
539 * (i.e. divide by 2**count).
540 * Store the len least significant words of the result at dest.
541 * OK if dest==x.
542 * Assumes: 0 <= count < 32
543 * Same as rshift, but handles count==0 (and has no return value).
544 */
545 public static void rshift0 (int[] dest, int[] x, int x_start,
546 int len, int count)
547 {
548 if (count > 0)
549 rshift(dest, x, x_start, len, count);
550 else
551 for (int i = 0; i < len; i++)
552 dest[i] = x[i + x_start];
553 }
554
555 /** Return the long-truncated value of right shifting.
556 * @param x a two's-complement "bignum"
557 * @param len the number of significant words in x
558 * @param count the shift count
559 * @return (long)(x[0..len-1] >> count).
560 */
561 public static long rshift_long (int[] x, int len, int count)
562 {
563 int wordno = count >> 5;
564 count &= 31;
565 int sign = x[len-1] < 0 ? -1 : 0;
566 int w0 = wordno >= len ? sign : x[wordno];
567 wordno++;
568 int w1 = wordno >= len ? sign : x[wordno];
569 if (count != 0)
570 {
571 wordno++;
572 int w2 = wordno >= len ? sign : x[wordno];
573 w0 = (w0 >>> count) | (w1 << (32-count));
574 w1 = (w1 >>> count) | (w2 << (32-count));
575 }
576 return ((long)w1 << 32) | ((long)w0 & 0xffffffffL);
577 }
578
579 /* Shift x[0:len-1] left by count bits, and store the len least
580 * significant words of the result in dest[d_offset:d_offset+len-1].
581 * Return the bits shifted out from the most significant digit.
582 * Assumes 0 < count < 32.
583 * OK if dest==x.
584 */
585
586 public static int lshift (int[] dest, int d_offset,
587 int[] x, int len, int count)
588 {
589 int count_2 = 32 - count;
590 int i = len - 1;
591 int high_word = x[i];
592 int retval = high_word >>> count_2;
593 d_offset++;
594 while (--i >= 0)
595 {
596 int low_word = x[i];
597 dest[d_offset+i] = (high_word << count) | (low_word >>> count_2);
598 high_word = low_word;
599 }
600 dest[d_offset+i] = high_word << count;
601 return retval;
602 }
603
604 /** Return least i such that word&(1<<i). Assumes word!=0. */
605
606 public static int findLowestBit (int word)
607 {
608 int i = 0;
609 while ((word & 0xF) == 0)
610 {
611 word >>= 4;
612 i += 4;
613 }
614 if ((word & 3) == 0)
615 {
616 word >>= 2;
617 i += 2;
618 }
619 if ((word & 1) == 0)
620 i += 1;
621 return i;
622 }
623
624 /** Return least i such that words & (1<<i). Assumes there is such an i. */
625
626 public static int findLowestBit (int[] words)
627 {
628 for (int i = 0; ; i++)
629 {
630 if (words[i] != 0)
631 return 32 * i + findLowestBit (words[i]);
632 }
633 }
634
635 /** Calculate Greatest Common Divisior of x[0:len-1] and y[0:len-1].
636 * Assumes both arguments are non-zero.
637 * Leaves result in x, and returns len of result.
638 * Also destroys y (actually sets it to a copy of the result). */
639
640 public static int gcd (int[] x, int[] y, int len)
641 {
642 int i, word;
643 // Find sh such that both x and y are divisible by 2**sh.
644 for (i = 0; ; i++)
645 {
646 word = x[i] | y[i];
647 if (word != 0)
648 {
649 // Must terminate, since x and y are non-zero.
650 break;
651 }
652 }
653 int initShiftWords = i;
654 int initShiftBits = findLowestBit (word);
655 // Logically: sh = initShiftWords * 32 + initShiftBits
656
657 // Temporarily devide both x and y by 2**sh.
658 len -= initShiftWords;
659 MPN.rshift0 (x, x, initShiftWords, len, initShiftBits);
660 MPN.rshift0 (y, y, initShiftWords, len, initShiftBits);
661
662 int[] odd_arg; /* One of x or y which is odd. */
663 int[] other_arg; /* The other one can be even or odd. */
664 if ((x[0] & 1) != 0)
665 {
666 odd_arg = x;
667 other_arg = y;
668 }
669 else
670 {
671 odd_arg = y;
672 other_arg = x;
673 }
674
675 for (;;)
676 {
677 // Shift other_arg until it is odd; this doesn't
678 // affect the gcd, since we divide by 2**k, which does not
679 // divide odd_arg.
680 for (i = 0; other_arg[i] == 0; ) i++;
681 if (i > 0)
682 {
683 int j;
684 for (j = 0; j < len-i; j++)
685 other_arg[j] = other_arg[j+i];
686 for ( ; j < len; j++)
687 other_arg[j] = 0;
688 }
689 i = findLowestBit(other_arg[0]);
690 if (i > 0)
691 MPN.rshift (other_arg, other_arg, 0, len, i);
692
693 // Now both odd_arg and other_arg are odd.
694
695 // Subtract the smaller from the larger.
696 // This does not change the result, since gcd(a-b,b)==gcd(a,b).
697 i = MPN.cmp(odd_arg, other_arg, len);
698 if (i == 0)
699 break;
700 if (i > 0)
701 { // odd_arg > other_arg
702 MPN.sub_n (odd_arg, odd_arg, other_arg, len);
703 // Now odd_arg is even, so swap with other_arg;
704 int[] tmp = odd_arg; odd_arg = other_arg; other_arg = tmp;
705 }
706 else
707 { // other_arg > odd_arg
708 MPN.sub_n (other_arg, other_arg, odd_arg, len);
709 }
710 while (odd_arg[len-1] == 0 && other_arg[len-1] == 0)
711 len--;
712 }
713 if (initShiftWords + initShiftBits > 0)
714 {
715 if (initShiftBits > 0)
716 {
717 int sh_out = MPN.lshift (x, initShiftWords, x, len, initShiftBits);
718 if (sh_out != 0)
719 x[(len++)+initShiftWords] = sh_out;
720 }
721 else
722 {
723 for (i = len; --i >= 0;)
724 x[i+initShiftWords] = x[i];
725 }
726 for (i = initShiftWords; --i >= 0; )
727 x[i] = 0;
728 len += initShiftWords;
729 }
730 return len;
731 }
732
733 public static int intLength (int i)
734 {
735 return 32 - count_leading_zeros (i < 0 ? ~i : i);
736 }
737
738 /** Calcaulte the Common Lisp "integer-length" function.
739 * Assumes input is canonicalized: len==BigInteger.wordsNeeded(words,len) */
740 public static int intLength (int[] words, int len)
741 {
742 len--;
743 return intLength (words[len]) + 32 * len;
744 }
745
746 /* DEBUGGING:
747 public static void dprint (BigInteger x)
748 {
749 if (x.words == null)
750 System.err.print(Long.toString((long) x.ival & 0xffffffffL, 16));
751 else
752 dprint (System.err, x.words, x.ival);
753 }
754 public static void dprint (int[] x) { dprint (System.err, x, x.length); }
755 public static void dprint (int[] x, int len) { dprint (System.err, x, len); }
756 public static void dprint (java.io.PrintStream ps, int[] x, int len)
757 {
758 ps.print('(');
759 for (int i = 0; i < len; i++)
760 {
761 if (i > 0)
762 ps.print (' ');
763 ps.print ("#x" + Long.toString ((long) x[i] & 0xffffffffL, 16));
764 }
765 ps.print(')');
766 }
767 */
768}
Note: See TracBrowser for help on using the repository browser.