grchiu 2003/01/09 14:42:41
Modified: java/src/org/apache/xpath/objects XNumber.java
XStringForFSB.java
Log:
Patch for bugzilla 14300.
Corrected algorithm for converting strings to numbers as it was failing on
very large or very small numbers.
Revision Changes Path
1.15 +6 -1 xml-xalan/java/src/org/apache/xpath/objects/XNumber.java
Index: XNumber.java
===================================================================
RCS file: /home/cvs/xml-xalan/java/src/org/apache/xpath/objects/XNumber.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- XNumber.java 5 Nov 2002 17:16:07 -0000 1.14
+++ XNumber.java 9 Jan 2003 22:42:41 -0000 1.15
@@ -342,7 +342,12 @@
int e = s.indexOf('E');
if (e < 0)
- return s;
+ {
+ if (s.charAt(len - 1) == '0')
+ return s.substring(0, len - 1);
+ else
+ return s;
+ }
int exp = Integer.parseInt(s.substring(e + 1));
String sign;
1.17 +31 -82
xml-xalan/java/src/org/apache/xpath/objects/XStringForFSB.java
Index: XStringForFSB.java
===================================================================
RCS file:
/home/cvs/xml-xalan/java/src/org/apache/xpath/objects/XStringForFSB.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- XStringForFSB.java 27 Jun 2002 14:50:42 -0000 1.16
+++ XStringForFSB.java 9 Jan 2003 22:42:41 -0000 1.17
@@ -990,91 +990,40 @@
* if the string can not be converted. */
public double toDouble()
{
- int end = m_length+m_start;
- if(0 == end)
+ if(m_length == 0)
return Double.NaN;
-
- int start = m_start;
- FastStringBuffer fsb = fsb();
-
- long longResult=0;
- boolean isNegative=false;
- boolean trailingSpace=false;
- int[] digitsFound={0,0}; // intpart,fracpart
- int digitType=0; // Index to which kind of digit we're accumulating
- double doubleResult;
+ int i;
+ char c;
+ String valueString = fsb().getString(m_start,m_length);
- // Scan past leading whitespace characters
- while(start< end &&
- XMLCharacterRecognizer.isWhiteSpace( fsb.charAt(start) )
- )
- ++start;
+ // The following are permitted in the Double.valueOf, but not by the
XPath spec:
+ // - a plus sign
+ // - The use of e or E to indicate exponents
+ // - trailing f, F, d, or D
+ // See function comments; not sure if this is slower than actually doing
the
+ // conversion ourselves (as was before).
- if (start < end && fsb.charAt(start) == '-')
- {
- isNegative=true;
- start++;
- }
-
- // parse the string from left to right converting as an integer.
- for (int i = start; i < end; i++)
- {
- char c = fsb.charAt(i);
-
- if(XMLCharacterRecognizer.isWhiteSpace(c))
- {
- trailingSpace=true;
- break; // Trailing whitespace is ignored
- }
- else if(trailingSpace)
- return Double.NaN; // Nonspace after space is poorly formed
-
- switch(c)
- {
- case '.':
- if(digitType==0)
- digitType=1;
- else
- return Double.NaN; // Second period is error
- break;
-
- case '0': // NOT Unicode isDigit(); ASCII digits
_only_
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- longResult = longResult * 10 + (c - '0'); // Accumulate as int
- ++digitsFound[digitType]; // Remember scaling
- break;
-
- default:
- return Double.NaN; // Nonnumeric is error
- }
- }
-
- if(0 ==digitsFound[0]&& 0==digitsFound[1])
+ for (i=0;i<m_length;i++)
+ if (!XMLCharacterRecognizer.isWhiteSpace(valueString.charAt(i)))
+ break;
+ if (valueString.charAt(i) == '-')
+ i++;
+ for (;i<m_length;i++) {
+ c = valueString.charAt(i);
+ if (c != '.' && (c < '0' || c > '9'))
+ break;
+ }
+ for (;i<m_length;i++)
+ if (!XMLCharacterRecognizer.isWhiteSpace(valueString.charAt(i)))
+ break;
+ if (i != m_length)
return Double.NaN;
-
- // Convert from scaled integer to floating point. This will come close.
- // There's an alternative solution involving Double.longBitsToDouble
- // followed by a combined renormalize/scale operation... but I honestly
- // think the more straightforward solution comes out to just about
- // the same thing.
-
- long scale=1; // AFAIK, java doesn't have an easier 10^n
operation
- for(int i=digitsFound[1];i>0;--i)
- scale*=10;
-
- doubleResult=((double)longResult)/scale;
-
- if(isNegative)
- doubleResult *= -1;
- return doubleResult;
+
+ try {
+ return new Double(valueString).doubleValue();
+ } catch (NumberFormatException nfe) {
+ // This should catch double periods, empty strings.
+ return Double.NaN;
+ }
}
-
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]