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