/* java.math.BigDecimal -- Arbitrary precision decimals.
   Copyright (C) 1999, 2000, 2001, 2003 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.math;

public class BigDecimal extends Number implements Comparable
{
  private BigInteger intVal;
  private int scale;
  private static final long serialVersionUID = 6108874887143696463L;

  private static final BigDecimal ZERO = 
    new BigDecimal (BigInteger.valueOf (0), 0);

  private static final BigDecimal ONE = 
    new BigDecimal (BigInteger.valueOf (1), 0);

  public static final int ROUND_UP = 0;
  public static final int ROUND_DOWN = 1;
  public static final int ROUND_CEILING = 2;
  public static final int ROUND_FLOOR = 3;
  public static final int ROUND_HALF_UP = 4;
  public static final int ROUND_HALF_DOWN = 5;
  public static final int ROUND_HALF_EVEN = 6;
  public static final int ROUND_UNNECESSARY = 7;

  public BigDecimal (BigInteger num) 
  {
    this (num, 0);
  }

  public BigDecimal (BigInteger num, int scale) throws NumberFormatException 
  {
    if (scale < 0) 
      throw new NumberFormatException ("scale of " + scale + " is < 0");
    this.intVal = num;
    this.scale = scale;
  }

  public BigDecimal (double num) throws NumberFormatException 
  {
    if (Double.isInfinite (num) || Double.isNaN (num))
      throw new NumberFormatException ("invalid argument: " + num);
    // Note we can't convert NUM to a String and then use the
    // String-based constructor.  The BigDecimal documentation makes
    // it clear that the two constructors work differently.

    final int mantissaBits = 52;
    final int exponentBits = 11;
    final long mantMask = (1L << mantissaBits) - 1;
    final long expMask = (1L << exponentBits) - 1;

    long bits = Double.doubleToLongBits (num);
    long mantissa = bits & mantMask;
    long exponent = (bits >>> mantissaBits) & expMask;
    boolean denormal = exponent == 0;
    // Correct the exponent for the bias.
    exponent -= denormal ? 1022 : 1023;
    // Now correct the exponent to account for the bits to the right
    // of the decimal.
    exponent -= mantissaBits;
    // Ordinary numbers have an implied leading `1' bit.
    if (! denormal)
      mantissa |= (1L << mantissaBits);

    // Shave off factors of 10.
    while (exponent < 0 && (mantissa & 1) == 0)
      {
	++exponent;
	mantissa >>= 1;
      }

    intVal = BigInteger.valueOf (bits < 0 ? - mantissa : mantissa);
    if (exponent < 0)
      {
	// We have MANTISSA * 2 ^ (EXPONENT).
	// Since (1/2)^N == 5^N * 10^-N we can easily convert this
	// into a power of 10.
	scale = (int) (- exponent);
	BigInteger mult = BigInteger.valueOf (5).pow (scale);
	intVal = intVal.multiply (mult);
      }
    else
      {
	intVal = intVal.shiftLeft ((int) exponent);
	scale = 0;
      }
  }

  public BigDecimal (String num) throws NumberFormatException 
  {
    int len = num.length();
    int start = 0, point = 0;
    int dot = -1;
    boolean negative = false;
    if (num.charAt(0) == '+')
      {
	++start;
	++point;
      }
    else if (num.charAt(0) == '-')
      {
	++start;
	++point;
	negative = true;
      }

    while (point < len)
      {
	char c = num.charAt (point);
	if (c == '.')
	  {
	    if (dot >= 0)
	      throw new NumberFormatException ("multiple `.'s in number");
	    dot = point;
	  }
	else if (c == 'e' || c == 'E')
	  break;
	else if (Character.digit (c, 10) < 0)
	  throw new NumberFormatException ("unrecognized character: " + c);
	++point;
      }

    String val;
    if (dot >= 0)
      {
	val = num.substring (start, dot) + num.substring (dot + 1, point);
	scale = point - 1 - dot;
      }
    else
      {
	val = num.substring (start, point);
	scale = 0;
      }
    if (val.length () == 0)
      throw new NumberFormatException ("no digits seen");

    if (negative)
      val = "-" + val;
    intVal = new BigInteger (val);

    // Now parse exponent.
    if (point < len)
      {
        point++;
        if (num.charAt(point) == '+')
          point++;

        if (point >= len )
          throw new NumberFormatException ("no exponent following e or E");
	
        try 
	  {
	    int exp = Integer.parseInt (num.substring (point));
	    exp -= scale;
	    if (signum () == 0)
	      scale = 0;
	    else if (exp > 0)
	      {
		intVal = intVal.multiply (BigInteger.valueOf (10).pow (exp));
		scale = 0;
	      }
	    else
	      scale = - exp;
	  }
        catch (NumberFormatException ex) 
	  {
	    throw new NumberFormatException ("malformed exponent");
	  }
      }
  }

  public static BigDecimal valueOf (long val) 
  {
    return valueOf (val, 0);
  }

  public static BigDecimal valueOf (long val, int scale) 
    throws NumberFormatException 
  {
    if ((scale == 0) && ((int)val == val))
      switch ((int) val)
	{
	case 0:
	  return ZERO;
	case 1:
	  return ONE;
	}

    return new BigDecimal (BigInteger.valueOf (val), scale);
  }

  public BigDecimal add (BigDecimal val) 
  {
    // For addition, need to line up decimals.  Note that the movePointRight
    // method cannot be used for this as it might return a BigDecimal with
    // scale == 0 instead of the scale we need.
    BigInteger op1 = intVal;
    BigInteger op2 = val.intVal;
    if (scale < val.scale)
      op1 = op1.multiply (BigInteger.valueOf (10).pow (val.scale - scale));
    else if (scale > val.scale)
      op2 = op2.multiply (BigInteger.valueOf (10).pow (scale - val.scale));

    return new BigDecimal (op1.add (op2), Math.max (scale, val.scale));
  }

  public BigDecimal subtract (BigDecimal val) 
  {
    return this.add(val.negate());
  }

  public BigDecimal multiply (BigDecimal val) 
  {
    return new BigDecimal (intVal.multiply (val.intVal), scale + val.scale);
  }

  public BigDecimal divide (BigDecimal val, int roundingMode) 
    throws ArithmeticException, IllegalArgumentException 
  {
    return divide (val, scale, roundingMode);
  }

  public BigDecimal divide(BigDecimal val, int newScale, int roundingMode)
    throws ArithmeticException, IllegalArgumentException 
  {
    if (roundingMode < 0 || roundingMode > 7)
      throw 
	new IllegalArgumentException("illegal rounding mode: " + roundingMode);

    if (newScale < 0)
      throw new ArithmeticException ("scale is negative: " + newScale);

    if (intVal.signum () == 0)	// handle special case of 0.0/0.0
      return newScale == 0 ? ZERO : new BigDecimal (ZERO.intVal, newScale);
    
    // Ensure that pow gets a non-negative value.
    BigInteger valIntVal = val.intVal;
    int power = newScale - (scale - val.scale);
    if (power < 0)
      {
	// Effectively increase the scale of val to avoid an
	// ArithmeticException for a negative power.
        valIntVal = valIntVal.multiply (BigInteger.valueOf (10).pow (-power));
	power = 0;
      }

    BigInteger dividend = intVal.multiply (BigInteger.valueOf (10).pow (power));
    
    BigInteger parts[] = dividend.divideAndRemainder (valIntVal);

    BigInteger unrounded = parts[0];
    if (parts[1].signum () == 0) // no remainder, no rounding necessary
      return new BigDecimal (unrounded, newScale);

    if (roundingMode == ROUND_UNNECESSARY)
      throw new ArithmeticException ("newScale is not large enough");

    int sign = intVal.signum () * valIntVal.signum ();

    if (roundingMode == ROUND_CEILING)
      roundingMode = (sign > 0) ? ROUND_UP : ROUND_DOWN;
    else if (roundingMode == ROUND_FLOOR)
      roundingMode = (sign < 0) ? ROUND_UP : ROUND_DOWN;
    else
      {
	// half is -1 if remainder*2 < positive intValue (*power), 0 if equal,
	// 1 if >. This implies that the remainder to round is less than,
	// equal to, or greater than half way to the next digit.
	BigInteger posRemainder
	  = parts[1].signum () < 0 ? parts[1].negate() : parts[1];
	valIntVal = valIntVal.signum () < 0 ? valIntVal.negate () : valIntVal;
	int half = posRemainder.shiftLeft(1).compareTo(valIntVal);

	switch(roundingMode)
	  {
	  case ROUND_HALF_UP:
	    roundingMode = (half < 0) ? ROUND_DOWN : ROUND_UP;
	    break;
	  case ROUND_HALF_DOWN:
	    roundingMode = (half > 0) ? ROUND_UP : ROUND_DOWN;
	    break;
	  case ROUND_HALF_EVEN:
	    if (half < 0)
	      roundingMode = ROUND_DOWN;
	    else if (half > 0)
	      roundingMode = ROUND_UP;
	    else if (unrounded.testBit(0)) // odd, then ROUND_HALF_UP
	      roundingMode = ROUND_UP;
	    else                           // even, ROUND_HALF_DOWN
	      roundingMode = ROUND_DOWN;
	    break;
	  }
      }

    if (roundingMode == ROUND_UP)
      unrounded = unrounded.add (BigInteger.valueOf (sign > 0 ? 1 : -1));

    // roundingMode == ROUND_DOWN
    return new BigDecimal (unrounded, newScale);
  }
    
  public int compareTo (BigDecimal val) 
  {
    if (scale == val.scale)
      return intVal.compareTo (val.intVal);

    BigInteger thisParts[] = 
      intVal.divideAndRemainder (BigInteger.valueOf (10).pow (scale));
    BigInteger valParts[] =
      val.intVal.divideAndRemainder (BigInteger.valueOf (10).pow (val.scale));
    
    int compare;
    if ((compare = thisParts[0].compareTo (valParts[0])) != 0)
      return compare;

    // quotients are the same, so compare remainders

    // remove trailing zeros
    if (thisParts[1].equals (BigInteger.valueOf (0)) == false)
      while (thisParts[1].mod (BigInteger.valueOf (10)).equals
	     (BigInteger.valueOf (0)))
      thisParts[1] = thisParts[1].divide (BigInteger.valueOf (10));
    // again...
    if (valParts[1].equals(BigInteger.valueOf (0)) == false)
      while (valParts[1].mod (BigInteger.valueOf (10)).equals
	     (BigInteger.valueOf (0)))
	valParts[1] = valParts[1].divide (BigInteger.valueOf (10));

    // and compare them
    return thisParts[1].compareTo (valParts[1]);
  }

  public int compareTo (Object val) 
  {
    return(compareTo((BigDecimal)val));
  }

  public boolean equals (Object o) 
  {
    return (o instanceof BigDecimal 
	    && scale == ((BigDecimal) o).scale
	    && compareTo ((BigDecimal) o) == 0);
  }

  public int hashCode() 
  {
    return intValue() ^ scale;
  }

  public BigDecimal max (BigDecimal val)
  {
    switch (compareTo (val)) 
      {
      case 1:
	return this;
      default:
	return val;
      }
  }

  public BigDecimal min (BigDecimal val) 
  {
    switch (compareTo (val)) 
      {
      case -1:
	return this;
      default:
	return val;
      }
  }

  public BigDecimal movePointLeft (int n)
  {
    return (n < 0) ? movePointRight (-n) : new BigDecimal (intVal, scale + n);
  }

  public BigDecimal movePointRight (int n)
  {
    if (n < 0)
      return movePointLeft (-n);

    if (scale >= n)
      return new BigDecimal (intVal, scale - n);

    return new BigDecimal (intVal.multiply 
			   (BigInteger.valueOf (10).pow (n - scale)), 0);
  }

  public int signum () 
  {
    return intVal.signum ();
  }

  public int scale () 
  {
    return scale;
  }
  
  public BigInteger unscaledValue()
  {
    return intVal;
  }

  public BigDecimal abs () 
  {
    return new BigDecimal (intVal.abs (), scale);
  }

  public BigDecimal negate () 
  {
    return new BigDecimal (intVal.negate (), scale);
  }

  public String toString () 
  {
    String bigStr = intVal.toString();
    if (scale == 0) 
      return bigStr;

    boolean negative = (bigStr.charAt(0) == '-');

    int point = bigStr.length() - scale - (negative ? 1 : 0);

    StringBuffer sb = new StringBuffer(bigStr.length() + 2 +
				       (point <= 0 ? (-point + 1) : 0));
    if (point <= 0)
      {
        if (negative)
          sb.append('-');
        sb.append('0').append('.');
        while (point < 0)
          {
            sb.append('0');
            point++;
          }
        sb.append(bigStr.substring(negative ? 1 : 0));
      }
    else
      {
	sb.append(bigStr);
	sb.insert(point + (negative ? 1 : 0), '.');
      }
    return sb.toString();
  }

  public BigInteger toBigInteger () 
  {
    return scale == 0 ? intVal :
      intVal.divide (BigInteger.valueOf (10).pow (scale));
  }

  public int intValue () 
  {
    return toBigInteger ().intValue ();
  }

  public long longValue ()
  {
    return toBigInteger().longValue();
  }

  public float floatValue() 
  {
    return Float.valueOf(toString()).floatValue();
  }

  public double doubleValue() 
  {
    return Double.valueOf(toString()).doubleValue();
  }

  public BigDecimal setScale (int scale) throws ArithmeticException
  {
    return setScale (scale, ROUND_UNNECESSARY);
  }

  public BigDecimal setScale (int scale, int roundingMode)
    throws ArithmeticException, IllegalArgumentException
  {
    return divide (ONE, scale, roundingMode);
  }
}
