< prev index next >

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

Print this page




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


4097         BigInteger[] cacheLine = powerCache[radix]; // volatile read
4098         if (exponent < cacheLine.length) {
4099             return cacheLine[exponent];
4100         }
4101 
4102         int oldLength = cacheLine.length;
4103         cacheLine = Arrays.copyOf(cacheLine, exponent + 1);
4104         for (int i = oldLength; i <= exponent; i++) {
4105             cacheLine[i] = cacheLine[i - 1].pow(2);
4106         }
4107 
4108         BigInteger[][] pc = powerCache; // volatile read again
4109         if (exponent >= pc[radix].length) {
4110             pc = pc.clone();
4111             pc[radix] = cacheLine;
4112             powerCache = pc; // volatile write, publish
4113         }
4114         return cacheLine[exponent];
4115     }
4116 
4117     /* Size of zeros string. */
4118     private static int NUM_ZEROS = 63;
4119 
4120     /* zero is a string of NUM_ZEROS consecutive zeros. */
4121     private static final String zeros = "0".repeat(NUM_ZEROS);
4122 
4123     /**
4124      * Returns the decimal String representation of this BigInteger.
4125      * The digit-to-character mapping provided by
4126      * {@code Character.forDigit} is used, and a minus sign is
4127      * prepended if appropriate.  (This representation is compatible
4128      * with the {@link #BigInteger(String) (String)} constructor, and
4129      * allows for String concatenation with Java's + operator.)
4130      *
4131      * @return decimal String representation of this BigInteger.
4132      * @see    Character#forDigit
4133      * @see    #BigInteger(java.lang.String)
4134      */
4135     public String toString() {
4136         return toString(10);
4137     }
4138 
4139     /**
4140      * Returns a byte array containing the two's-complement
4141      * representation of this BigInteger.  The byte array will be in




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     private static void padWithZeros(StringBuilder buf, int len, int digits) {
3964         if (digits > 0 && len < digits) {
3965             int m = digits - len;
3966             while (m >= NUM_ZEROS) {
3967                 buf.append(ZEROS);
3968                 m -= NUM_ZEROS;
3969             }
3970             if (m > 0) {
3971                 buf.append(ZEROS, 0, m);
3972             }
3973         }
3974     }
3975 
3976     /**
3977      * This method is used to perform toString when arguments are small.
3978      * A negative sign will be prepended if and only if {@code this < 0}.
3979      * If {@code digits <= 0} no padding (pre-pending with zeros) will be
3980      * effected.
3981      *
3982      * @param radix  The base to convert to.
3983      * @param sb     The StringBuilder that will be appended to in place.
3984      * @param digits The minimum number of digits to pad to.
3985      */
3986     private void smallToString(int radix, StringBuilder buf, int digits) {
3987         if (signum == 0) {
3988             buf.append('0');
3989             padWithZeros(buf, 1, digits);
3990             return;
3991         }
3992 
3993         // Put sign (if any) into result buffer
3994         if (signum < 0) {
3995             buf.append('-');
3996         }
3997 
3998         // Compute upper bound on number of digit groups and allocate space
3999         int maxNumDigitGroups = (4*mag.length + 6)/7;
4000         long[] digitGroups = new long[maxNumDigitGroups];
4001 
4002         // Translate number to string, a digit group at a time
4003         BigInteger tmp = this.abs();
4004         int numGroups = 0;
4005         while (tmp.signum != 0) {
4006             BigInteger d = longRadix[radix];
4007 
4008             MutableBigInteger q = new MutableBigInteger(),
4009                               a = new MutableBigInteger(tmp.mag),
4010                               b = new MutableBigInteger(d.mag);
4011             MutableBigInteger r = a.divide(b, q);
4012             BigInteger q2 = q.toBigInteger(tmp.signum * d.signum);
4013             BigInteger r2 = r.toBigInteger(tmp.signum * d.signum);
4014 
4015             digitGroups[numGroups++] = r2.longValue();
4016             tmp = q2;
4017         }
4018 
4019         // Get string version of first digit group
4020         String s = Long.toString(digitGroups[numGroups-1], radix);
4021 
4022         // Pad with internal zeros if necessary.
4023         padWithZeros(buf, s.length() + (numGroups - 1)*digitsPerLong[radix],
4024             digits);











4025 
4026         // Put first digit group into result buffer
4027         buf.append(s);
4028 
4029         // Append remaining digit groups each padded with leading zeros
4030         for (int i=numGroups-2; i >= 0; i--) {
4031             // Prepend (any) leading zeros for this digit group
4032             s = Long.toString(digitGroups[i], radix);
4033             int numLeadingZeros = digitsPerLong[radix] - s.length();
4034             if (numLeadingZeros != 0) {
4035                 buf.append(ZEROS, 0, numLeadingZeros);
4036             }
4037             buf.append(s);
4038         }
4039     }
4040 
4041     /**
4042      * Converts the specified BigInteger to a string and appends to
4043      * {@code sb}.  This implements the recursive Schoenhage algorithm
4044      * for base conversions.
4045      * <p>
4046      * See Knuth, Donald,  _The Art of Computer Programming_, Vol. 2,
4047      * Answers to Exercises (4.4) Question 14.
4048      *
4049      * @param u      The number to convert to a string.
4050      * @param sb     The StringBuilder that will be appended to in place.
4051      * @param radix  The base to convert to.
4052      * @param digits The minimum number of digits to pad to.
4053      */
4054     private static void toString(BigInteger u, StringBuilder sb,
4055                                  int radix, int digits) {


4100         BigInteger[] cacheLine = powerCache[radix]; // volatile read
4101         if (exponent < cacheLine.length) {
4102             return cacheLine[exponent];
4103         }
4104 
4105         int oldLength = cacheLine.length;
4106         cacheLine = Arrays.copyOf(cacheLine, exponent + 1);
4107         for (int i = oldLength; i <= exponent; i++) {
4108             cacheLine[i] = cacheLine[i - 1].pow(2);
4109         }
4110 
4111         BigInteger[][] pc = powerCache; // volatile read again
4112         if (exponent >= pc[radix].length) {
4113             pc = pc.clone();
4114             pc[radix] = cacheLine;
4115             powerCache = pc; // volatile write, publish
4116         }
4117         return cacheLine[exponent];
4118     }
4119 
4120     /* Size of ZEROS string. */
4121     private static int NUM_ZEROS = 63;
4122 
4123     /* ZEROS is a string of NUM_ZEROS consecutive zeros. */
4124     private static final String ZEROS = "0".repeat(NUM_ZEROS);
4125 
4126     /**
4127      * Returns the decimal String representation of this BigInteger.
4128      * The digit-to-character mapping provided by
4129      * {@code Character.forDigit} is used, and a minus sign is
4130      * prepended if appropriate.  (This representation is compatible
4131      * with the {@link #BigInteger(String) (String)} constructor, and
4132      * allows for String concatenation with Java's + operator.)
4133      *
4134      * @return decimal String representation of this BigInteger.
4135      * @see    Character#forDigit
4136      * @see    #BigInteger(java.lang.String)
4137      */
4138     public String toString() {
4139         return toString(10);
4140     }
4141 
4142     /**
4143      * Returns a byte array containing the two's-complement
4144      * representation of this BigInteger.  The byte array will be in


< prev index next >