You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ap...@apache.org on 2007/02/01 10:51:18 UTC
svn commit: r502174 - in
/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math:
BigDecimal.java BigInteger.java Conversion.java
Author: apetrenko
Date: Thu Feb 1 01:51:17 2007
New Revision: 502174
URL: http://svn.apache.org/viewvc?view=rev&rev=502174
Log:
Patch for HARMONY-3089 "[math] performance related improvements in java.math.BigDecimal/java.math.BigInteger/java.math."
Modified:
harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java
harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java
harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/Conversion.java
Modified: harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java?view=diff&rev=502174&r1=502173&r2=502174
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java (original)
+++ harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigDecimal.java Thu Feb 1 01:51:17 2007
@@ -234,7 +234,7 @@
int begin = offset; // first index to be copied
int last = offset + (len - 1); // last index to be copied
String scaleString = null; // buffer for scale
- StringBuffer unscaledBuffer; // buffer for unscaled value
+ StringBuilder unscaledBuffer; // buffer for unscaled value
long newScale; // the new scale
if (in == null) {
@@ -243,18 +243,29 @@
if ((last >= in.length) || (offset < 0) || (len <= 0) || (last < 0)) {
throw new NumberFormatException();
}
- unscaledBuffer = new StringBuffer(len);
+ unscaledBuffer = new StringBuilder(len);
+ int bufLength = 0;
// To skip a possible '+' symbol
if ((offset <= last) && (in[offset] == '+')) {
offset++;
begin++;
}
+ int counter = 0;
+ boolean wasNonZero = false;
// Accumulating all digits until a possible decimal point
for (; (offset <= last) && (in[offset] != '.')
&& (in[offset] != 'e') && (in[offset] != 'E'); offset++) {
- ;
+ if (!wasNonZero) {
+ if (in[offset] == '0') {
+ counter++;
+ } else {
+ wasNonZero = true;
+ }
+ };
+
}
unscaledBuffer.append(in, begin, offset - begin);
+ bufLength += offset - begin;
// A decimal point was found
if ((offset <= last) && (in[offset] == '.')) {
offset++;
@@ -262,9 +273,16 @@
begin = offset;
for (; (offset <= last) && (in[offset] != 'e')
&& (in[offset] != 'E'); offset++) {
- ;
+ if (!wasNonZero) {
+ if (in[offset] == '0') {
+ counter++;
+ } else {
+ wasNonZero = true;
+ }
+ };
}
scale = offset - begin;
+ bufLength +=scale;
unscaledBuffer.append(in, begin, scale);
} else {
scale = 0;
@@ -291,7 +309,16 @@
}
}
// Parsing the unscaled value
- setUnscaledValue(new BigInteger(unscaledBuffer.toString()));
+ if (bufLength < 19) {
+ smallValue = Long.parseLong(unscaledBuffer.toString());
+ bitLength = bitLength(smallValue);
+ } else {
+ setUnscaledValue(new BigInteger(unscaledBuffer.toString()));
+ }
+ precision = unscaledBuffer.length() - counter;
+ if (unscaledBuffer.charAt(0) == '-') {
+ precision --;
+ }
}
/** @ar.org.fitc.spec_ref */
@@ -1732,10 +1759,13 @@
* @see #round(MathContext).
*/
private void inplaceRound(MathContext mc) {
- int mcPrecision = mc.getPrecision();
+ int mcPrecision = mc.getPrecision();
+ if (aproxPrecision() - mcPrecision <= 0 || mcPrecision == 0) {
+ return;
+ }
int discardedPrecision = precision() - mcPrecision;
// If no rounding is necessary it returns immediately
- if ((discardedPrecision <= 0) || (mcPrecision == 0)) {
+ if ((discardedPrecision <= 0)) {
return;
}
// When the number is small perform an efficient rounding
Modified: harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java?view=diff&rev=502174&r1=502173&r2=502174
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java (original)
+++ harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/BigInteger.java Thu Feb 1 01:51:17 2007
@@ -143,10 +143,7 @@
// math.12=Zero length BigInteger
throw new NumberFormatException(Messages.getString("math.12")); //$NON-NLS-1$
}
- BigInteger me = Conversion.string2BigInteger(val, radix);
- sign = me.sign;
- numberLength = me.numberLength;
- digits = me.digits;
+ setFromString(this, val, radix);
}
/** @ar.org.fitc.spec_ref */
@@ -274,6 +271,7 @@
return new BigInteger(1, val);
}
}
+
/** @ar.org.fitc.spec_ref */
public byte[] toByteArray() {
@@ -339,6 +337,64 @@
}
return bytes;
}
+
+ /** @see BigInteger#BigInteger(String, int) */
+ private static void setFromString(BigInteger bi, String val, int radix) {
+ int sign;
+ int[] digits;
+ int numberLength;
+ int stringLength = val.length();
+ int startChar;
+ int endChar = stringLength;
+
+ if (val.charAt(0) == '-') {
+ sign = -1;
+ startChar = 1;
+ stringLength--;
+ } else {
+ sign = 1;
+ startChar = 0;
+ }
+ /*
+ * We use the following algorithm: split a string into portions of n
+ * characters and convert each portion to an integer according to the
+ * radix. Then convert an exp(radix, n) based number to binary using the
+ * multiplication method. See D. Knuth, The Art of Computer Programming,
+ * vol. 2.
+ */
+
+ int charsPerInt = Conversion.digitFitInInt[radix];
+ int bigRadixDigitsLength = stringLength / charsPerInt;
+ int topChars = stringLength % charsPerInt;
+
+ if (topChars != 0) {
+ bigRadixDigitsLength++;
+ }
+ digits = new int[bigRadixDigitsLength];
+ // Get the maximal power of radix that fits in int
+ int bigRadix = Conversion.bigRadices[radix - 2];
+ // Parse an input string and accumulate the BigInteger's magnitude
+ int digitIndex = 0; // index of digits array
+ int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars);
+ int newDigit;
+
+ for (int substrStart = startChar; substrStart < endChar; substrStart = substrEnd, substrEnd = substrStart
+ + charsPerInt) {
+ int bigRadixDigit = Integer.parseInt(val.substring(substrStart,
+ substrEnd), radix);
+ newDigit = Multiplication.multiplyByInt(digits, digitIndex,
+ bigRadix);
+ newDigit += Elementary
+ .inplaceAdd(digits, digitIndex, bigRadixDigit);
+ digits[digitIndex++] = newDigit;
+ }
+ numberLength = digitIndex;
+ bi.sign = sign;
+ bi.numberLength = numberLength;
+ bi.digits = digits;
+ bi.cutOffLeadingZeroes();
+ }
+
/** @ar.org.fitc.spec_ref */
public BigInteger abs() {
Modified: harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/Conversion.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/Conversion.java?view=diff&rev=502174&r1=502173&r2=502174
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/Conversion.java (original)
+++ harmony/enhanced/classlib/trunk/modules/math/src/main/java/java/math/Conversion.java Thu Feb 1 01:51:17 2007
@@ -33,7 +33,7 @@
* Holds the maximal exponent for each radix, so that radix<sup>digitFitInInt[radix]</sup>
* fit in an {@code int} (32 bits).
*/
- private static final int[] digitFitInInt = { -1, -1, 31, 19, 15, 13, 11,
+ static final int[] digitFitInInt = { -1, -1, 31, 19, 15, 13, 11,
11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 5 };
@@ -43,7 +43,7 @@
* 2 ^ 31, bigRadices[8] = 10 ^ 9, etc.
*/
- private static final int bigRadices[] = { -2147483648, 1162261467,
+ static final int bigRadices[] = { -2147483648, 1162261467,
1073741824, 1220703125, 362797056, 1977326743, 1073741824,
387420489, 1000000000, 214358881, 429981696, 815730721, 1475789056,
170859375, 268435456, 410338673, 612220032, 893871739, 1280000000,
@@ -51,63 +51,7 @@
387420489, 481890304, 594823321, 729000000, 887503681, 1073741824,
1291467969, 1544804416, 1838265625, 60466176 };
- /** @see BigInteger#BigInteger(String, int) */
- static BigInteger string2BigInteger(String val, int radix) {
- int sign;
- int[] digits;
- int numberLength;
- int stringLength = val.length();
- int startChar;
- int endChar = stringLength;
-
- if (val.charAt(0) == '-') {
- sign = -1;
- startChar = 1;
- stringLength--;
- } else {
- sign = 1;
- startChar = 0;
- }
- /*
- * We use the following algorithm: split a string into portions of n
- * characters and convert each portion to an integer according to the
- * radix. Then convert an exp(radix, n) based number to binary using the
- * multiplication method. See D. Knuth, The Art of Computer Programming,
- * vol. 2.
- */
-
- int charsPerInt = digitFitInInt[radix];
- int bigRadixDigitsLength = stringLength / charsPerInt;
- int topChars = stringLength % charsPerInt;
-
- if (topChars != 0) {
- bigRadixDigitsLength++;
- }
- digits = new int[bigRadixDigitsLength];
- // Get the maximal power of radix that fits in int
- int bigRadix = bigRadices[radix - 2];
- // Parse an input string and accumulate the BigInteger's magnitude
- int digitIndex = 0; // index of digits array
- int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars);
- int newDigit;
- BigInteger result;
-
- for (int substrStart = startChar; substrStart < endChar; substrStart = substrEnd, substrEnd = substrStart
- + charsPerInt) {
- int bigRadixDigit = Integer.parseInt(val.substring(substrStart,
- substrEnd), radix);
- newDigit = Multiplication.multiplyByInt(digits, digitIndex,
- bigRadix);
- newDigit += Elementary
- .inplaceAdd(digits, digitIndex, bigRadixDigit);
- digits[digitIndex++] = newDigit;
- }
- numberLength = digitIndex;
- result = new BigInteger(sign, numberLength, digits);
- result.cutOffLeadingZeroes();
- return result;
- }
-
+
/** @see BigInteger#toString(int) */
static String bigInteger2String(BigInteger val, int radix) {
int sign = val.sign;