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;