< prev index next >
src/java.base/share/classes/java/math/BigInteger.java
Print this page
@@ -3935,74 +3935,74 @@
if (signum == 0)
return "0";
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
+ BigInteger abs = this.abs();
+
// Ensure buffer capacity sufficient to contain string representation
// floor(bitLength*log(2)/log(radix)) + 1
// plus an additional character for the sign if negative.
- int b = this.abs().bitLength();
+ int b = abs.bitLength();
int numChars = (int)(Math.floor(b*LOG_TWO/logCache[radix]) + 1) +
(signum < 0 ? 1 : 0);
StringBuilder sb = new StringBuilder(numChars);
- // If it's small enough, use smallToString.
- if (mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD) {
- // smallToString() will prepend a negative sign if this < 0,
- // but will not pad with any leading zeros.
- smallToString(radix, sb, -1);
- return sb.toString();
+ if (signum < 0) {
+ sb.append('-');
}
- // Otherwise use recursive toString.
- // The results will be concatenated into this StringBuilder
- toString(this, sb, radix, 0);
+ // Use recursive toString.
+ toString(abs, sb, radix, 0);
return sb.toString();
}
- private static void padWithZeros(StringBuilder buf, int len, int digits) {
- if (digits > 0 && len < digits) {
- int m = digits - len;
- while (m >= NUM_ZEROS) {
+ /**
+ * If {@code numZeros > 0}, appends that many zeros to the
+ * specified StringBuilder; otherwise, does nothing.
+ *
+ * @param sb The StringBuilder that will be appended to.
+ * @param numZeros The number of zeros to append.
+ */
+ private static void padWithZeros(StringBuilder buf, int numZeros) {
+ while (numZeros >= NUM_ZEROS) {
buf.append(ZEROS);
- m -= NUM_ZEROS;
- }
- if (m > 0) {
- buf.append(ZEROS, 0, m);
+ numZeros -= NUM_ZEROS;
}
+ if (numZeros > 0) {
+ buf.append(ZEROS, 0, numZeros);
}
}
/**
* This method is used to perform toString when arguments are small.
- * A negative sign will be prepended if and only if {@code this < 0}.
- * If {@code digits <= 0} no padding (pre-pending with zeros) will be
- * effected.
+ * The value must be non-negative. If {@code digits <= 0} no padding
+ * (pre-pending with zeros) will be effected.
*
* @param radix The base to convert to.
* @param sb The StringBuilder that will be appended to in place.
* @param digits The minimum number of digits to pad to.
*/
private void smallToString(int radix, StringBuilder buf, int digits) {
+ assert signum >= 0;
+
if (signum == 0) {
+ if (digits > 0) {
+ padWithZeros(buf, digits);
+ } else {
buf.append('0');
- padWithZeros(buf, 1, digits);
- return;
}
-
- // Put sign (if any) into result buffer
- if (signum < 0) {
- buf.append('-');
+ return;
}
// Compute upper bound on number of digit groups and allocate space
int maxNumDigitGroups = (4*mag.length + 6)/7;
long[] digitGroups = new long[maxNumDigitGroups];
// Translate number to string, a digit group at a time
- BigInteger tmp = this.abs();
+ BigInteger tmp = this;
int numGroups = 0;
while (tmp.signum != 0) {
BigInteger d = longRadix[radix];
MutableBigInteger q = new MutableBigInteger(),
@@ -4018,12 +4018,12 @@
// Get string version of first digit group
String s = Long.toString(digitGroups[numGroups-1], radix);
// Pad with internal zeros if necessary.
- padWithZeros(buf, s.length() + (numGroups - 1)*digitsPerLong[radix],
- digits);
+ padWithZeros(buf, digits - (s.length() +
+ (numGroups - 1)*digitsPerLong[radix]));
// Put first digit group into result buffer
buf.append(s);
// Append remaining digit groups each padded with leading zeros
@@ -4039,11 +4039,12 @@
}
/**
* Converts the specified BigInteger to a string and appends to
* {@code sb}. This implements the recursive Schoenhage algorithm
- * for base conversions.
+ * for base conversions. This method can only be called for non-negative
+ * numbers.
* <p>
* See Knuth, Donald, _The Art of Computer Programming_, Vol. 2,
* Answers to Exercises (4.4) Question 14.
*
* @param u The number to convert to a string.
@@ -4051,25 +4052,18 @@
* @param radix The base to convert to.
* @param digits The minimum number of digits to pad to.
*/
private static void toString(BigInteger u, StringBuilder sb,
int radix, int digits) {
- // We're at the beginning if nothing is in the StringBuilder.
- boolean atBeginning = sb.length() == 0;
-
- // Make negative values positive and prepend a negative sign.
- if (u.signum() < 0) {
- u = u.negate();
- sb.append('-');
- }
+ assert u.signum() >= 0;
// If we're smaller than a certain threshold, use the smallToString
// method, padding with leading zeroes when necessary unless we're
// at the beginning of the string or digits <= 0. As u.signum() >= 0,
// smallToString() will not prepend a negative sign.
if (u.mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD) {
- u.smallToString(radix, sb, atBeginning ? -1 : digits);
+ u.smallToString(radix, sb, digits);
return;
}
// Calculate a value for n in the equation radix^(2^n) = u
// and subtract 1 from that value. This is used to find the
@@ -4083,11 +4077,11 @@
results = u.divideAndRemainder(v);
int expectedDigits = 1 << n;
// Now recursively build the two halves of each number.
- toString(results[0], sb, radix, digits-expectedDigits);
+ toString(results[0], sb, radix, digits - expectedDigits);
toString(results[1], sb, radix, expectedDigits);
}
/**
* Returns the value radix^(2^exponent) from the cache.
< prev index next >