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]

Reply via email to