From 4baba9f150e4013de41d1f05f567ff14d9af3db4 Mon Sep 17 00:00:00 2001 From: bothner Date: Fri, 2 Mar 2001 06:55:33 +0000 Subject: [PATCH] Changes merged from Kawa's gnu.math. * java/math/BigInteger.java * gnu/gcj/math/MPN.java (rshift0): New method handles zero shift count. (rshift(int[],int[],int,int): Removed - not needed. (gcd): Use rshift0 rather than rshift. * java/math/BigInteger.java (setShiftRight): Likewise. (divide): Simplify by using rshift0. (divide): Zero-extend results if high-order bit set. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@40177 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/ChangeLog | 11 ++++++++++ libjava/gnu/gcj/math/MPN.java | 43 +++++++++++++++++++++------------------ libjava/java/math/BigInteger.java | 25 +++++++++-------------- 3 files changed, 44 insertions(+), 35 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index b0f3031ba34..d0b8e6a43be 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,14 @@ +2001-03-01 Per Bothner + + Changes merged from Kawa's gnu.math. + * java/math/BigInteger.java + * gnu/gcj/math/MPN.java (rshift0): New method handles zero shift count. + (rshift(int[],int[],int,int): Removed - not needed. + (gcd): Use rshift0 rather than rshift. + * java/math/BigInteger.java (setShiftRight): Likewise. + (divide): Simplify by using rshift0. + (divide): Zero-extend results if high-order bit set. + 2001-02-27 Bryce McKinlay * libgcj.spec.in: Insert %(libgcc) before %(liborig) to fix static diff --git a/libjava/gnu/gcj/math/MPN.java b/libjava/gnu/gcj/math/MPN.java index fb947a5a699..879b1733236 100644 --- a/libjava/gnu/gcj/math/MPN.java +++ b/libjava/gnu/gcj/math/MPN.java @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation +/* Copyright (C) 1999, 2000, 2001 Free Software Foundation This file is part of libgcj. @@ -481,7 +481,7 @@ public class MPN return xlen > ylen ? 1 : xlen < ylen ? -1 : cmp (x, y, xlen); } - /* Shift x[x_start:x_start+len-1]count bits to the "right" + /* Shift x[x_start:x_start+len-1] count bits to the "right" * (i.e. divide by 2**count). * Store the len least significant words of the result at dest. * The bits shifted out to the right are returned. @@ -506,6 +506,23 @@ public class MPN return retval; } + /* Shift x[x_start:x_start+len-1] count bits to the "right" + * (i.e. divide by 2**count). + * Store the len least significant words of the result at dest. + * OK if dest==x. + * Assumes: 0 <= count < 32 + * Same as rshift, but handles count==0 (and has no return value). + */ + public static void rshift0 (int[] dest, int[] x, int x_start, + int len, int count) + { + if (count > 0) + rshift(dest, x, x_start, len, count); + else + for (int i = 0; i < len; i++) + dest[i] = x[i + x_start]; + } + /** Return the long-truncated value of right shifting. * @param x a two's-complement "bignum" * @param len the number of significant words in x @@ -530,20 +547,6 @@ public class MPN return ((long)w1 << 32) | ((long)w0 & 0xffffffffL); } - /* Shift x[0:len-1]count bits to the "right" (i.e. divide by 2**count). - * Store the len least significant words of the result at dest. - * OK if dest==x. - * OK if count > 32 (but must be >= 0). - */ - public static void rshift (int[] dest, int[] x, int len, int count) - { - int word_count = count >> 5; - count &= 31; - rshift (dest, x, word_count, len, count); - while (word_count < len) - dest[word_count++] = 0; - } - /* Shift x[0:len-1] left by count bits, and store the len least * significant words of the result in dest[d_offset:d_offset+len-1]. * Return the bits shifted out from the most significant digit. @@ -624,8 +627,8 @@ public class MPN // Temporarily devide both x and y by 2**sh. len -= initShiftWords; - MPN.rshift (x, x, initShiftWords, len, initShiftBits); - MPN.rshift (y, y, initShiftWords, len, initShiftBits); + MPN.rshift0 (x, x, initShiftWords, len, initShiftBits); + MPN.rshift0 (y, y, initShiftWords, len, initShiftBits); int[] odd_arg; /* One of x or y which is odd. */ int[] other_arg; /* The other one can be even or odd. */ @@ -704,7 +707,7 @@ public class MPN } /** Calcaulte the Common Lisp "integer-length" function. - * Assumes input is canonicalized: len==IntNum.wordsNeeded(words,len) */ + * Assumes input is canonicalized: len==BigInteger.wordsNeeded(words,len) */ public static int intLength (int[] words, int len) { len--; @@ -712,7 +715,7 @@ public class MPN } /* DEBUGGING: - public static void dprint (IntNum x) + public static void dprint (BigInteger x) { if (x.words == null) System.err.print(Long.toString((long) x.ival & 0xffffffffL, 16)); diff --git a/libjava/java/math/BigInteger.java b/libjava/java/math/BigInteger.java index 0d8608eecc3..1d848d13e8f 100644 --- a/libjava/java/math/BigInteger.java +++ b/libjava/java/math/BigInteger.java @@ -794,13 +794,7 @@ public class BigInteger extends Number implements Comparable xwords[xlen++] = 0; MPN.divide(xwords, xlen, ywords, ylen); rlen = ylen; - if (remainder != null || rounding_mode != TRUNCATE) - { - if (nshift == 0) - System.arraycopy(xwords, 0, ywords, 0, rlen); - else - MPN.rshift(ywords, xwords, 0, rlen, nshift); - } + MPN.rshift0 (ywords, xwords, 0, rlen, nshift); qlen = xlen + 1 - ylen; if (quotient != null) @@ -810,6 +804,12 @@ public class BigInteger extends Number implements Comparable } } + if (ywords[rlen-1] < 0) + { + ywords[rlen] = 0; + rlen++; + } + // Now the quotient is in xwords, and the remainder is in ywords. boolean add_one = false; @@ -1399,15 +1399,10 @@ public class BigInteger extends Number implements Comparable { if (words == null || words.length < d_len) realloc(d_len); - if (count == 0) - System.arraycopy(x.words, word_count, words, 0, d_len); - else - { - MPN.rshift(words, x.words, word_count, d_len, count); - if (neg) - words[d_len-1] |= -1 << (32 - count); - } + MPN.rshift0 (words, x.words, word_count, d_len, count); ival = d_len; + if (neg) + words[d_len-1] |= -1 << (32 - count); } } } -- 2.11.0