jkesselm 02/02/04 11:01:14
Modified: java/src/org/apache/xpath/objects XStringForFSB.java
Log:
Bugzilla 5346: My first-cut messed up fractional values. This one is
somewhat better.
There's an open issue w/r/t numbers with many digits after the
decimal point, regarding limits on how large a power of 10 can
be contained in a long. In that one case I'm falling back on successive
divisions (though as few as possible), and some loss of precision
may result.
Need to find a better algorithm...
Revision Changes Path
1.10 +30 -13
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.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- XStringForFSB.java 4 Feb 2002 17:13:16 -0000 1.9
+++ XStringForFSB.java 4 Feb 2002 19:01:14 -0000 1.10
@@ -996,7 +996,8 @@
boolean trailingSpace=false;
int[] digitsFound={0,0}; // intpart,fracpart
int digitType=0; // Index to which kind of digit we're accumulating
- double doubleResult=0;
+ double doubleResult;
+ int overflow=0;
// Scan past leading whitespace characters
while(start< end &&
@@ -1048,15 +1049,14 @@
// %REVIEW% Is it possible that we should be accepting _some_
// of the bits of the new digit, but not all of them?
long newResult = longResult * 10 + (c - '0');
- if(newResult>0)
+ if(newResult>=0)
{
longResult=newResult;
++digitsFound[digitType]; // Remember scaling
}
else
- {
- --digitsFound[1]; // Just scale up by 10, later
- }
+ ++overflow;
+
break;
default:
@@ -1075,18 +1075,35 @@
long scale=1; // AFAIK, java doesn't have an easier 10^n
operation
- if(digitsFound[1]>0) // Normal fractional-part processing
+ doubleResult=(double)longResult;
+ if(digitsFound[1]==0) // Integer overflow scaling
{
- for(int i=digitsFound[1];i>0;--i)
- scale*=10;
- doubleResult=((double)longResult)/scale;
+ for(int i=overflow;i>0;--i)
+ scale*=10;
+ doubleResult*=scale;
}
- else // Case where int-part
overflow exceeds frac-part length
+ else // Fractional-part
scaling
{
- for(int i=digitsFound[1];i<0;++i)
- scale*=10;
- doubleResult=((double)longResult)*scale;
+ // Complication: In values <0, the fractional part may want to be
divided
+ // by a power of 10 too large to fit in a long! In that case, resort to
+ // successive divisions.
+ //
+ // %REVIEW% This can't be a good solution. Need a better algorithm.
+
+ int i=digitsFound[1];
+ while(i>0)
+ {
+ int j=(i<18) ? i : 18;
+ i-=j;
+
+ for(scale=1;j>0;--j)
+ scale*=10;
+
+ doubleResult/=scale;
+ }
}
+
+ /***/System.out.println("GONK "+doubleResult);
if(isNegative)
doubleResult *= -1;
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]