/* java.math.BigDecimal -- Arbitrary precision decimals.
   Copyright (C) 1999, 2000, 2001 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;

import java.math.BigInteger;

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

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

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

  public final static int ROUND_UP = 0;
  public final static int ROUND_DOWN = 1;
  public final static int ROUND_CEILING = 2;
  public final static int ROUND_FLOOR = 3;
  public final static int ROUND_HALF_UP = 4;
  public final static int ROUND_HALF_DOWN = 5;
  public final static int ROUND_HALF_EVEN = 6;
  public final static 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)
      {
	int exp = Integer.parseInt (num.substring (point + 1));
	exp -= scale;
	if (exp > 0)
	  {
	    intVal = intVal.multiply (BigInteger.valueOf (10).pow (exp));
	    scale = 0;
	  }
	else
	  scale = - exp;
      }
  }

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

  public static BigDecimal valueOf (long val, int scale) 
    throws NumberFormatException 
  {
    if (scale == 0)
      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 ZERO;
    
    // Ensure that pow gets a non-negative value.
    int valScale = val.scale;
    BigInteger valIntVal = val.intVal;
    int power = newScale + 1 - (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);
//      System.out.println("int: " + parts[0]);
//      System.out.println("rem: " + parts[1]);

    int roundDigit = parts[0].mod (BigInteger.valueOf (10)).intValue ();
    BigInteger unrounded = parts[0].divide (BigInteger.valueOf (10));

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

    int sign = unrounded.signum ();

    switch (roundingMode)
      {
      case ROUND_UNNECESSARY:
	throw new ArithmeticException ("newScale is not large enough");
      case ROUND_CEILING:
	roundingMode = (sign == 1) ? ROUND_UP : ROUND_DOWN;
	break;
      case ROUND_FLOOR:
	roundingMode = (sign == 1) ? ROUND_DOWN : ROUND_UP;
	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
	  {
	    int rightmost = 
	      unrounded.mod (BigInteger.valueOf (10)).intValue ();
	    if (rightmost % 2 == 1) // odd, then ROUND_HALF_UP
	      roundingMode = ROUND_UP;
	    else // even, then ROUND_HALF_DOWN
	      roundingMode = (roundDigit > 5) ? ROUND_UP : ROUND_DOWN;
	  }
	break;
      }

    if (roundingMode == ROUND_UP)
      return new BigDecimal (unrounded.add (BigInteger.valueOf (1)), newScale);

    // 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 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;

    int point = bigStr.length() - scale;
    boolean negative = (bigStr.charAt(0) == '-');
    StringBuffer sb = new StringBuffer(bigStr.length() + 1 + 
				       (point <= 0 ? -point+1 : 0));
    if (negative)
      sb.append('-');
    while (point <= 0)
      {
	sb.append('0');
	point++;
      }
    sb.append(bigStr.substring(negative ? 1 : 0));
    sb.insert(point, '.');
    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);
  }
}
