< prev index next >
src/java.base/share/classes/java/math/BigInteger.java
Print this page
*** 3935,4008 ****
if (signum == 0)
return "0";
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
radix = 10;
// 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 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();
}
! // Otherwise use recursive toString.
! // The results will be concatenated into this StringBuilder
! toString(this, 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) {
buf.append(ZEROS);
! m -= NUM_ZEROS;
! }
! if (m > 0) {
! buf.append(ZEROS, 0, m);
}
}
}
/**
* 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.
*
* @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) {
if (signum == 0) {
buf.append('0');
- padWithZeros(buf, 1, digits);
- return;
}
!
! // Put sign (if any) into result buffer
! if (signum < 0) {
! buf.append('-');
}
// 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();
int numGroups = 0;
while (tmp.signum != 0) {
BigInteger d = longRadix[radix];
MutableBigInteger q = new MutableBigInteger(),
--- 3935,4008 ----
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 = abs.bitLength();
int numChars = (int)(Math.floor(b*LOG_TWO/logCache[radix]) + 1) +
(signum < 0 ? 1 : 0);
StringBuilder sb = new StringBuilder(numChars);
! if (signum < 0) {
! sb.append('-');
}
! // Use recursive toString.
! toString(abs, sb, radix, 0);
return sb.toString();
}
! /**
! * 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);
! numZeros -= NUM_ZEROS;
}
+ if (numZeros > 0) {
+ buf.append(ZEROS, 0, numZeros);
}
}
/**
* This method is used to perform toString when arguments are small.
! * 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');
}
! 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;
int numGroups = 0;
while (tmp.signum != 0) {
BigInteger d = longRadix[radix];
MutableBigInteger q = new MutableBigInteger(),
*** 4018,4029 ****
// 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);
// Put first digit group into result buffer
buf.append(s);
// Append remaining digit groups each padded with leading zeros
--- 4018,4029 ----
// Get string version of first digit group
String s = Long.toString(digitGroups[numGroups-1], radix);
// Pad with internal zeros if necessary.
! 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,4049 ****
}
/**
* Converts the specified BigInteger to a string and appends to
* {@code sb}. This implements the recursive Schoenhage algorithm
! * for base conversions.
* <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.
--- 4039,4050 ----
}
/**
* Converts the specified BigInteger to a string and appends to
* {@code sb}. This implements the recursive Schoenhage algorithm
! * 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,4075 ****
* @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('-');
! }
// 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);
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
--- 4052,4069 ----
* @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) {
! 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, 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,4093 ****
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[1], sb, radix, expectedDigits);
}
/**
* Returns the value radix^(2^exponent) from the cache.
--- 4077,4087 ----
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[1], sb, radix, expectedDigits);
}
/**
* Returns the value radix^(2^exponent) from the cache.
< prev index next >