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