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