< 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 >