You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by jk...@apache.org on 2001/10/15 17:31:11 UTC
cvs commit: xml-xalan/java/src/org/apache/xpath/objects XStringForFSB.java
jkesselm 01/10/15 08:31:11
Modified: java/src/org/apache/xpath/objects XStringForFSB.java
Log:
Bugzilla 3384. See comments in the toDouble method; I suspect this may be wasted micro-optimization.
Revision Changes Path
1.4 +61 -64 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.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- XStringForFSB.java 2001/06/18 02:16:14 1.3
+++ XStringForFSB.java 2001/10/15 15:31:11 1.4
@@ -961,94 +961,91 @@
* Convert a string to a double -- Allowed input is in fixed
* notation ddd.fff.
*
+ * %OPT% CHECK PERFORMANCE against generating a Java String and
+ * converting it to double. The advantage of running in native
+ * machine code -- perhaps even microcode, on some systems -- may
+ * more than make up for the cost of allocating and discarding the
+ * additional object. We need to benchmark this.
+ *
+ * %OPT% More importantly, we need to decide whether we _care_ about
+ * the performance of this operation. Does XString.toDouble constitute
+ * any measurable percentage of our typical runtime? I suspect not!
+ *
* @return A double value representation of the string, or return Double.NaN
- * if the string can not be converted.
- */
+ * if the string can not be converted. */
public double toDouble()
{
-
- int start = m_start;
- int end = m_length+start;
-
+ int end = m_length+m_start;
if(0 == end)
return Double.NaN;
-
- double result = 0.0;
- int punctPos = end-1;
+
+ int start = m_start;
FastStringBuffer fsb = fsb();
+
+ long longResult=0;
+ boolean isNegative=false;
+ int[] digitsFound={0,0}; // intpart,fracpart
+ int digitType=0; // Index to which kind of digit we're accumulating
+ double doubleResult;
- // Scan to first whitespace character.
- for (int i = start; i < end; i++)
- {
- char c = fsb.charAt(i);
- if( !XMLCharacterRecognizer.isWhiteSpace( c ) )
- {
- break;
- }
- else
- start++;
- }
-
- double sign = 1.0;
+ // Scan past whitespace characters
+ while(start< end &&
+ XMLCharacterRecognizer.isWhiteSpace( fsb.charAt(start) )
+ )
+ ++start;
+
if (start < end && fsb.charAt(start) == '-')
{
- sign = -1.0;
-
+ isNegative=true;
start++;
}
- int digitsFound = 0;
- for (int i = start; i < end; i++) // parse the string from left to right converting the integer part
+ // parse the string from left to right converting as an integer.
+ for (int i = start; i < end; i++)
{
char c = fsb.charAt(i);
- if (c != '.')
+
+ if (c == '.')
{
- if(XMLCharacterRecognizer.isWhiteSpace(c))
- break;
- else if (Character.isDigit(c))
- {
- result = result * 10.0 + (c - 0x30);
- digitsFound++;
- }
+ if(digitType==0)
+ digitType=1;
else
- {
- return Double.NaN;
- }
+ return Double.NaN; // Second period is error
}
- else
- {
- punctPos = i;
+
+ else if(XMLCharacterRecognizer.isWhiteSpace(c))
+ break; // Whitespace is ignored
- break;
- }
- }
-
- if (fsb.charAt(punctPos) == '.') // parse the string from the end to the '.' converting the fractional part
- {
- double fractPart = 0.0;
- for (int i = end - 1; i > punctPos; i--)
+ else if (Character.isDigit(c))
{
- char c = fsb.charAt(i);
- if(XMLCharacterRecognizer.isWhiteSpace(c))
- continue;
- else if (Character.isDigit(c))
- {
- fractPart = fractPart / 10.0 + (c - 0x30);
- digitsFound++;
- }
- else
- {
- return Double.NaN;
- }
+ longResult = longResult * 10 + (c - '0'); // Accumulate as int
+ ++digitsFound[digitType]; // Remember scaling
}
- result += fractPart / 10.0;
+ else
+ {
+ return Double.NaN; // Nonnumeric is error
+ }
}
-
- if(0 == digitsFound)
+
+ if(0 ==digitsFound[0]&& 0==digitsFound[1])
return Double.NaN;
- return result * sign;
+ // 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;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org