This is the mail archive of the
kawa@sourceware.cygnus.com
mailing list for the Kawa project.
Re: Bug in Arithmetic (kawa/gnu.math)
- To: "Otto, Marcus" <Otto_Marcus at ph-ludwigsburg dot de>
- Subject: Re: Bug in Arithmetic (kawa/gnu.math)
- From: Per Bothner <per at bothner dot com>
- Date: 29 Apr 2000 12:26:38 -0700
- Cc: kawa at sourceware dot cygnus dot com
- References: <1BAAA1B1263@ph-ludwigsburg.de>
"Otto, Marcus" <Otto_Marcus@ph-ludwigsburg.de> writes:
> I traced the error back to the gcd method of gnu.math.IntNum
> which behaves buggy when used with one arg larger than
> (expt 2 32) and the other being odd like 3,5,7,9,11,13,15,...
> (I didn't test any further)
Thanks for reporting this!
> I guess, there is something mixed up with the 2-complement
> and 32-Bit word-wise representation of IntNum.
No. The problem turned out to be using MPN.rshift with a zero shift
count, which it is documented to not support (just like gmp's
mpn_rshift).
> Is this bug already known?
No, your's is the first report.
> Is there a fix or workaround?
Here it is. I checked it and soem related changes into cvs.
Index: MPN.java
===================================================================
RCS file: /cvs/kawa/kawa/gnu/math/MPN.java,v
retrieving revision 1.10
diff -u -r1.10 MPN.java
--- MPN.java 1998/05/16 04:42:51 1.10
+++ MPN.java 2000/04/29 19:07:57
@@ -498,6 +498,23 @@
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
@@ -616,8 +619,8 @@
// 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. */
--
--Per Bothner
per@bothner.com http://www.bothner.com/~per/