/[classpath]/classpath/java/math/BigDecimal.java
ViewVC logotype

Diff of /classpath/java/math/BigDecimal.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.14 by tromey, Sat Apr 19 19:25:25 2003 UTC revision 1.15 by mark, Fri Jul 18 11:00:10 2003 UTC
# Line 1  Line 1 
1  /* java.math.BigDecimal -- Arbitrary precision decimals.  /* java.math.BigDecimal -- Arbitrary precision decimals.
2     Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.     Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 273  public class BigDecimal extends Number i Line 273  public class BigDecimal extends Number i
273      // Ensure that pow gets a non-negative value.      // Ensure that pow gets a non-negative value.
274      int valScale = val.scale;      int valScale = val.scale;
275      BigInteger valIntVal = val.intVal;      BigInteger valIntVal = val.intVal;
276      int power = newScale + 1 - (scale - val.scale);      int power = newScale - (scale - val.scale);
277      if (power < 0)      if (power < 0)
278        {        {
279          // Effectively increase the scale of val to avoid an          // Effectively increase the scale of val to avoid an
# Line 288  public class BigDecimal extends Number i Line 288  public class BigDecimal extends Number i
288  //      System.out.println("int: " + parts[0]);  //      System.out.println("int: " + parts[0]);
289  //      System.out.println("rem: " + parts[1]);  //      System.out.println("rem: " + parts[1]);
290    
291      int roundDigit = parts[0].mod (BigInteger.valueOf (10)).intValue ();      BigInteger unrounded = parts[0];
292      BigInteger unrounded = parts[0].divide (BigInteger.valueOf (10));      if (parts[1].signum () == 0) // no remainder, no rounding necessary
   
     if (roundDigit == 0 && parts[1].signum () == 0) // no rounding necessary  
293        return new BigDecimal (unrounded, newScale);        return new BigDecimal (unrounded, newScale);
294    
295        if (roundingMode == ROUND_UNNECESSARY)
296          throw new ArithmeticException ("newScale is not large enough");
297    
298      int sign = unrounded.signum ();      int sign = unrounded.signum ();
299    
300      switch (roundingMode)      if (roundingMode == ROUND_CEILING)
301          roundingMode = (sign == 1) ? ROUND_UP : ROUND_DOWN;
302        else if (roundingMode == ROUND_FLOOR)
303          roundingMode = (sign == 1) ? ROUND_DOWN : ROUND_UP;
304        else
305        {        {
306        case ROUND_UNNECESSARY:          // half is -1 if remainder*2 < positive intValue (*power), 0 if equal,
307          throw new ArithmeticException ("newScale is not large enough");          // 1 if >. This implies that the remainder to round is less than,
308        case ROUND_CEILING:          // equal to, or greater than half way to the next digit.
309          roundingMode = (sign == 1) ? ROUND_UP : ROUND_DOWN;          BigInteger posRemainder = sign == -1 ? parts[1].negate() : parts[1];
310          break;          int half = posRemainder.shiftLeft(1).compareTo(valIntVal);
311        case ROUND_FLOOR:          
312          roundingMode = (sign == 1) ? ROUND_DOWN : ROUND_UP;          switch(roundingMode)
         break;  
       case ROUND_HALF_UP:  
         roundingMode = (roundDigit >= 5) ? ROUND_UP : ROUND_DOWN;  
         break;  
       case ROUND_HALF_DOWN:  
         roundingMode = (roundDigit > 5) ? ROUND_UP : ROUND_DOWN;  
         break;  
       case ROUND_HALF_EVEN:  
         if (roundDigit < 5)  
           roundingMode = ROUND_DOWN;  
         else  
313            {            {
314              int rightmost =            case ROUND_HALF_UP:
315                unrounded.mod (BigInteger.valueOf (10)).intValue ();              roundingMode = (half == -1) ? ROUND_DOWN : ROUND_UP;
316              if (rightmost % 2 == 1) // odd, then ROUND_HALF_UP              break;
317              case ROUND_HALF_DOWN:
318                roundingMode = (half == 1) ? ROUND_UP : ROUND_DOWN;
319                break;
320              case ROUND_HALF_EVEN:
321                if (half == -1)
322                  roundingMode = ROUND_DOWN;
323                else if (half == 1)
324                  roundingMode = ROUND_UP;
325                else if (unrounded.testBit(0)) // odd, then ROUND_HALF_UP
326                roundingMode = ROUND_UP;                roundingMode = ROUND_UP;
327              else // even, then ROUND_HALF_DOWN              else                           // even, ROUND_HALF_DOWN
328                roundingMode = (roundDigit > 5) ? ROUND_UP : ROUND_DOWN;                roundingMode = ROUND_DOWN;
329                break;
330            }            }
         break;  
331        }        }
332    
333      if (roundingMode == ROUND_UP)      if (roundingMode == ROUND_UP)
334        return new BigDecimal (unrounded.add (BigInteger.valueOf (1)), newScale);        return new BigDecimal (unrounded.add (BigInteger.valueOf
335                                                (sign != 0 ? sign : 1)), newScale);
336    
337      // roundingMode == ROUND_DOWN      // roundingMode == ROUND_DOWN
338      return new BigDecimal (unrounded, newScale);      return new BigDecimal (unrounded, newScale);

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26