< prev index next >

src/java.base/share/classes/java/math/BigInteger.java

Print this page




3930      * @see    Integer#toString
3931      * @see    Character#forDigit
3932      * @see    #BigInteger(java.lang.String, int)
3933      */
3934     public String toString(int radix) {
3935         if (signum == 0)
3936             return "0";
3937         if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
3938             radix = 10;
3939 
3940         // Ensure buffer capacity sufficient to contain string representation
3941         //     floor(bitLength*log(2)/log(radix)) + 1
3942         // plus an additional character for the sign if negative.
3943         int b = this.abs().bitLength();
3944         int numChars = (int)(Math.floor(b*LOG_TWO/logCache[radix]) + 1) +
3945             (signum < 0 ? 1 : 0);
3946         StringBuilder sb = new StringBuilder(numChars);
3947 
3948         // If it's small enough, use smallToString.
3949         if (mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD) {
3950             smallToString(radix, sb);


3951             return sb.toString();
3952         }
3953 
3954         // Otherwise use recursive toString.
3955         // The results will be concatenated into this StringBuilder
3956         toString(this, sb, radix, 0);
3957 
3958         return sb.toString();
3959     }
3960 
3961     /** This method is used to perform toString when arguments are small. */
3962     private int smallToString(int radix, StringBuilder buf) {









3963         if (signum == 0) {
3964             buf.append('0');
3965             return 1;





3966         }
3967 
3968         // Compute upper bound on number of digit groups and allocate space
3969         int maxNumDigitGroups = (4*mag.length + 6)/7;
3970         long[] digitGroups = new long[maxNumDigitGroups];
3971 
3972         // Translate number to string, a digit group at a time
3973         BigInteger tmp = this.abs();
3974         int numGroups = 0;
3975         while (tmp.signum != 0) {
3976             BigInteger d = longRadix[radix];
3977 
3978             MutableBigInteger q = new MutableBigInteger(),
3979                               a = new MutableBigInteger(tmp.mag),
3980                               b = new MutableBigInteger(d.mag);
3981             MutableBigInteger r = a.divide(b, q);
3982             BigInteger q2 = q.toBigInteger(tmp.signum * d.signum);
3983             BigInteger r2 = r.toBigInteger(tmp.signum * d.signum);
3984 
3985             digitGroups[numGroups++] = r2.longValue();
3986             tmp = q2;
3987         }
3988 
3989         int count = 0;

3990 
3991         // Put sign (if any) and first digit group into result buffer
3992         if (signum < 0) {
3993             buf.append('-');
3994             count++;




3995         }
3996         String s = Long.toString(digitGroups[numGroups-1], radix);






3997         buf.append(s);
3998         count += s.length();
3999 
4000         // Append remaining digit groups padded with leading zeros
4001         for (int i=numGroups-2; i >= 0; i--) {
4002             // Prepend (any) leading zeros for this digit group
4003             s = Long.toString(digitGroups[i], radix);
4004             int numLeadingZeros = digitsPerLong[radix] - s.length();
4005             if (numLeadingZeros != 0) {
4006                 buf.append(zeros, 0, numLeadingZeros);
4007                 count += numLeadingZeros;
4008             }
4009             buf.append(s);
4010             count += s.length();
4011         }
4012 
4013         return count;
4014     }
4015 
4016     /**
4017      * Converts the specified BigInteger to a string and appends to
4018      * {@code sb}.  This implements the recursive Schoenhage algorithm
4019      * for base conversions.
4020      * <p>
4021      * See Knuth, Donald,  _The Art of Computer Programming_, Vol. 2,
4022      * Answers to Exercises (4.4) Question 14.
4023      *
4024      * @param u      The number to convert to a string.
4025      * @param sb     The StringBuilder that will be appended to in place.
4026      * @param radix  The base to convert to.
4027      * @param digits The minimum number of digits to pad to.
4028      */
4029     private static void toString(BigInteger u, StringBuilder sb,
4030                                  int radix, int digits) {

4031         boolean atBeginning = sb.length() == 0;


4032         if (u.signum() < 0) {
4033             u = u.negate();
4034             sb.append('-');
4035         }
4036 
4037         // If we're smaller than a certain threshold, use the smallToString
4038         // method, padding with leading zeroes when necessary.


4039         if (u.mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD) {
4040             // Save current position.
4041             int pos = sb.length();
4042             int len = u.smallToString(radix, sb);
4043 
4044             // Pad with internal zeros if necessary.
4045             // Don't pad if we're at the beginning of the string.
4046             if (!atBeginning && len < digits) {
4047                 int m = digits - len;
4048                 while (m >= NUM_ZEROS) {
4049                     sb.insert(pos, zeros, 0, NUM_ZEROS);
4050                     pos += NUM_ZEROS;
4051                     m -= NUM_ZEROS;
4052                 }
4053                 if (m > 0) {
4054                     sb.insert(pos, zeros, 0, m);
4055                 }
4056             }
4057 
4058             return;
4059         }
4060 
4061         int b = u.bitLength();
4062 
4063         // Calculate a value for n in the equation radix^(2^n) = u
4064         // and subtract 1 from that value.  This is used to find the
4065         // cache index that contains the best value to divide u.

4066         int n = (int) Math.round(Math.log(b * LOG_TWO / logCache[radix]) /
4067                                  LOG_TWO - 1.0);

4068         BigInteger v = getRadixConversionCache(radix, n);
4069         BigInteger[] results;
4070         results = u.divideAndRemainder(v);
4071 
4072         int expectedDigits = 1 << n;
4073 
4074         // Now recursively build the two halves of each number.
4075         toString(results[0], sb, radix, digits-expectedDigits);
4076         toString(results[1], sb, radix, expectedDigits);
4077     }
4078 
4079     /**
4080      * Returns the value radix^(2^exponent) from the cache.
4081      * If this value doesn't already exist in the cache, it is added.
4082      * <p>
4083      * This could be changed to a more complicated caching method using
4084      * {@code Future}.
4085      */
4086     private static BigInteger getRadixConversionCache(int radix, int exponent) {
4087         BigInteger[] cacheLine = powerCache[radix]; // volatile read




3930      * @see    Integer#toString
3931      * @see    Character#forDigit
3932      * @see    #BigInteger(java.lang.String, int)
3933      */
3934     public String toString(int radix) {
3935         if (signum == 0)
3936             return "0";
3937         if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
3938             radix = 10;
3939 
3940         // Ensure buffer capacity sufficient to contain string representation
3941         //     floor(bitLength*log(2)/log(radix)) + 1
3942         // plus an additional character for the sign if negative.
3943         int b = this.abs().bitLength();
3944         int numChars = (int)(Math.floor(b*LOG_TWO/logCache[radix]) + 1) +
3945             (signum < 0 ? 1 : 0);
3946         StringBuilder sb = new StringBuilder(numChars);
3947 
3948         // If it's small enough, use smallToString.
3949         if (mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD) {
3950             // smallToString() will prepend a negative sign if this < 0,
3951             // but will not pad with any leading zeros.
3952             smallToString(radix, sb, -1);
3953             return sb.toString();
3954         }
3955 
3956         // Otherwise use recursive toString.
3957         // The results will be concatenated into this StringBuilder
3958         toString(this, sb, radix, 0);
3959 
3960         return sb.toString();
3961     }
3962 
3963     /**
3964      * This method is used to perform toString when arguments are small.
3965      * A negative sign will be prepended if and only if {@code this < 0}.
3966      * If {@code digits <= 0} no padding (pre-pending with zeros) will be
3967      * effected.
3968      *
3969      * @param radix  The base to convert to.
3970      * @param sb     The StringBuilder that will be appended to in place.
3971      * @param digits The minimum number of digits to pad to.
3972      */
3973     private void smallToString(int radix, StringBuilder buf, int digits) {
3974         if (signum == 0) {
3975             buf.append('0');
3976             return;
3977         }
3978 
3979         // Put sign (if any) into result buffer
3980         if (signum < 0) {
3981             buf.append('-');
3982         }
3983 
3984         // Compute upper bound on number of digit groups and allocate space
3985         int maxNumDigitGroups = (4*mag.length + 6)/7;
3986         long[] digitGroups = new long[maxNumDigitGroups];
3987 
3988         // Translate number to string, a digit group at a time
3989         BigInteger tmp = this.abs();
3990         int numGroups = 0;
3991         while (tmp.signum != 0) {
3992             BigInteger d = longRadix[radix];
3993 
3994             MutableBigInteger q = new MutableBigInteger(),
3995                               a = new MutableBigInteger(tmp.mag),
3996                               b = new MutableBigInteger(d.mag);
3997             MutableBigInteger r = a.divide(b, q);
3998             BigInteger q2 = q.toBigInteger(tmp.signum * d.signum);
3999             BigInteger r2 = r.toBigInteger(tmp.signum * d.signum);
4000 
4001             digitGroups[numGroups++] = r2.longValue();
4002             tmp = q2;
4003         }
4004 
4005         // Get string version of first digit group
4006         String s = Long.toString(digitGroups[numGroups-1], radix);
4007 
4008         // Pad with internal zeros if necessary.
4009         if (digits > 0) {
4010             int len = s.length() + (numGroups - 1)*digitsPerLong[radix];
4011             if (len < digits) {
4012                 int m = digits - len;
4013                 while (m >= NUM_ZEROS) {
4014                     buf.append(zeros);
4015                     m -= NUM_ZEROS;
4016                 }
4017                 if (m > 0) {
4018                     buf.append(zeros, 0, m);
4019                 }
4020             }
4021         }
4022 
4023         // Put first digit group into result buffer
4024         buf.append(s);

4025 
4026         // Append remaining digit groups each padded with leading zeros
4027         for (int i=numGroups-2; i >= 0; i--) {
4028             // Prepend (any) leading zeros for this digit group
4029             s = Long.toString(digitGroups[i], radix);
4030             int numLeadingZeros = digitsPerLong[radix] - s.length();
4031             if (numLeadingZeros != 0) {
4032                 buf.append(zeros, 0, numLeadingZeros);

4033             }
4034             buf.append(s);

4035         }


4036     }
4037 
4038     /**
4039      * Converts the specified BigInteger to a string and appends to
4040      * {@code sb}.  This implements the recursive Schoenhage algorithm
4041      * for base conversions.
4042      * <p>
4043      * See Knuth, Donald,  _The Art of Computer Programming_, Vol. 2,
4044      * Answers to Exercises (4.4) Question 14.
4045      *
4046      * @param u      The number to convert to a string.
4047      * @param sb     The StringBuilder that will be appended to in place.
4048      * @param radix  The base to convert to.
4049      * @param digits The minimum number of digits to pad to.
4050      */
4051     private static void toString(BigInteger u, StringBuilder sb,
4052                                  int radix, int digits) {
4053         // We're at the beginning if nothing is in the StringBuilder.
4054         boolean atBeginning = sb.length() == 0;
4055 
4056         // Make negative values positive and prepend a negative sign.
4057         if (u.signum() < 0) {
4058             u = u.negate();
4059             sb.append('-');
4060         }
4061 
4062         // If we're smaller than a certain threshold, use the smallToString
4063         // method, padding with leading zeroes when necessary unless we're
4064         // at the beginning of the string or digits <= 0. As u.signum() >= 0,
4065         // smallToString() will not prepend a negative sign.
4066         if (u.mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD) {
4067             u.smallToString(radix, sb, atBeginning ? -1 : digits);

















4068             return;
4069         }
4070 


4071         // Calculate a value for n in the equation radix^(2^n) = u
4072         // and subtract 1 from that value.  This is used to find the
4073         // cache index that contains the best value to divide u.
4074         int b = u.bitLength();
4075         int n = (int) Math.round(Math.log(b * LOG_TWO / logCache[radix]) /
4076                                  LOG_TWO - 1.0);
4077 
4078         BigInteger v = getRadixConversionCache(radix, n);
4079         BigInteger[] results;
4080         results = u.divideAndRemainder(v);
4081 
4082         int expectedDigits = 1 << n;
4083 
4084         // Now recursively build the two halves of each number.
4085         toString(results[0], sb, radix, digits-expectedDigits);
4086         toString(results[1], sb, radix, expectedDigits);
4087     }
4088 
4089     /**
4090      * Returns the value radix^(2^exponent) from the cache.
4091      * If this value doesn't already exist in the cache, it is added.
4092      * <p>
4093      * This could be changed to a more complicated caching method using
4094      * {@code Future}.
4095      */
4096     private static BigInteger getRadixConversionCache(int radix, int exponent) {
4097         BigInteger[] cacheLine = powerCache[radix]; // volatile read


< prev index next >