< prev index next >

src/java.base/share/classes/java/math/BigInteger.java

Print this page

        

*** 40,49 **** --- 40,50 ---- import jdk.internal.math.DoubleConsts; import jdk.internal.math.FloatConsts; import jdk.internal.HotSpotIntrinsicCandidate; import jdk.internal.vm.annotation.Stable; + import jdk.internal.vm.annotation.ForceInline; /** * Immutable arbitrary-precision integers. All operations behave as if * BigIntegers were represented in two's-complement notation (like Java's * primitive integer types). BigInteger provides analogues to all of Java's
*** 2619,2648 **** } } // shifts a up to len right n bits assumes no leading zeros, 0<n<32 static void primitiveRightShift(int[] a, int len, int n) { ! int n2 = 32 - n; ! for (int i=len-1, c=a[i]; i > 0; i--) { ! int b = c; ! c = a[i-1]; ! a[i] = (c << n2) | (b >>> n); ! } a[0] >>>= n; } // shifts a up to len left n bits assumes no leading zeros, 0<=n<32 static void primitiveLeftShift(int[] a, int len, int n) { if (len == 0 || n == 0) return; ! ! int n2 = 32 - n; ! for (int i=0, c=a[i], m=i+len-1; i < m; i++) { ! int b = c; ! c = a[i+1]; ! a[i] = (b << n) | (c >>> n2); ! } a[len-1] <<= n; } /** * Calculate bitlength of contents of the first len elements an int array, --- 2620,2640 ---- } } // shifts a up to len right n bits assumes no leading zeros, 0<n<32 static void primitiveRightShift(int[] a, int len, int n) { ! Objects.checkFromToIndex(0, len, a.length); ! shiftRightImplWorker(a, a, 1, n, len-1); a[0] >>>= n; } // shifts a up to len left n bits assumes no leading zeros, 0<=n<32 static void primitiveLeftShift(int[] a, int len, int n) { if (len == 0 || n == 0) return; ! Objects.checkFromToIndex(0, len, a.length); ! shiftLeftImplWorker(a, a, 0, n, len-1); a[len-1] <<= n; } /** * Calculate bitlength of contents of the first len elements an int array,
*** 3351,3368 **** newMag = new int[magLen + nInts + 1]; newMag[i++] = highBits; } else { newMag = new int[magLen + nInts]; } ! int j=0; ! while (j < magLen-1) ! newMag[i++] = mag[j++] << nBits | mag[j] >>> nBits2; ! newMag[i] = mag[j] << nBits; } return newMag; } /** * Returns a BigInteger whose value is {@code (this >> n)}. Sign * extension is performed. The shift distance, {@code n}, may be * negative, in which case this method performs a left shift. * (Computes <code>floor(this / 2<sup>n</sup>)</code>.) --- 3343,3371 ---- newMag = new int[magLen + nInts + 1]; newMag[i++] = highBits; } else { newMag = new int[magLen + nInts]; } ! int numIter = magLen - 1; ! Objects.checkFromToIndex(0, numIter + 1, mag.length); ! Objects.checkFromToIndex(i, numIter + i + 1, newMag.length); ! shiftLeftImplWorker(newMag, mag, i, nBits, numIter); ! newMag[numIter + i] = mag[numIter] << nBits; } return newMag; } + @ForceInline + @HotSpotIntrinsicCandidate + private static void shiftLeftImplWorker(int[] newArr, int[] oldArr, int newIdx, int shiftCount, int numIter) { + int shiftCountRight = 32 - shiftCount; + int oldIdx = 0; + while (oldIdx < numIter) { + newArr[newIdx++] = (oldArr[oldIdx++] << shiftCount) | (oldArr[oldIdx] >>> shiftCountRight); + } + } + /** * Returns a BigInteger whose value is {@code (this >> n)}. Sign * extension is performed. The shift distance, {@code n}, may be * negative, in which case this method performs a left shift. * (Computes <code>floor(this / 2<sup>n</sup>)</code>.)
*** 3413,3427 **** newMag = new int[magLen - nInts]; newMag[i++] = highBits; } else { newMag = new int[magLen - nInts -1]; } ! ! int nBits2 = 32 - nBits; ! int j=0; ! while (j < magLen - nInts - 1) ! newMag[i++] = (mag[j++] << nBits2) | (mag[j] >>> nBits); } if (signum < 0) { // Find out whether any one-bits were shifted off the end. boolean onesLost = false; --- 3416,3429 ---- newMag = new int[magLen - nInts]; newMag[i++] = highBits; } else { newMag = new int[magLen - nInts -1]; } ! int numIter = magLen - nInts - 1; ! Objects.checkFromToIndex(0, numIter + 1, mag.length); ! Objects.checkFromToIndex(i, numIter + i, newMag.length); ! shiftRightImplWorker(newMag, mag, i, nBits, numIter); } if (signum < 0) { // Find out whether any one-bits were shifted off the end. boolean onesLost = false;
*** 3435,3444 **** --- 3437,3457 ---- } return new BigInteger(newMag, signum); } + @ForceInline + @HotSpotIntrinsicCandidate + private static void shiftRightImplWorker(int[] newArr, int[] oldArr, int newIdx, int shiftCount, int numIter) { + int shiftCountLeft = 32 - shiftCount; + int idx = numIter; + int nidx = (newIdx == 0) ? numIter - 1 : numIter; + while (nidx >= newIdx) { + newArr[nidx--] = (oldArr[idx--] >>> shiftCount) | (oldArr[idx] << shiftCountLeft); + } + } + int[] javaIncrement(int[] val) { int lastSum = 0; for (int i=val.length-1; i >= 0 && lastSum == 0; i--) lastSum = (val[i] += 1); if (lastSum == 0) {
< prev index next >