home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / math / BigDecimal.java next >
Encoding:
Java Source  |  1998-03-20  |  24.4 KB  |  671 lines

  1. /*
  2.  * @(#)BigDecimal.java    1.12 98/03/18
  3.  *
  4.  * Copyright 1996, 1997 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.math;
  16.  
  17. /**
  18.  * Immutable, arbitrary-precision signed decimal numbers.  A BigDecimal
  19.  * consists of an arbitrary precision integer value and a non-negative
  20.  * integer scale, which represents the number of decimal digits to the
  21.  * right of the decimal point.  (The number represented by the BigDecimal
  22.  * is intVal/10**scale.)  BigDecimals provide operations for basic arithmetic,
  23.  * scale manipulation, comparison, format conversion and hashing.
  24.  *
  25.  * <p>The BigDecimal class gives its user complete control over rounding
  26.  * behavior, forcing the user to explicitly specify a rounding behavior for
  27.  * operations capable of discarding precision (divide and setScale).  Eight
  28.  * <em>rounding modes</em> are provided for this purpose.
  29.  *
  30.  * Two types of operations are provided for manipulating the scale of a
  31.  * BigDecimal: scaling/rounding operations and decimal point motion operations.
  32.  * Scaling/Rounding operations (SetScale) return a BigDecimal whose value is
  33.  * approximately (or exactly) equal to that of the operand, but whose scale is
  34.  * the specified value; that is, they increase or decrease the precision
  35.  * of the number with minimal effect on its value.  Decimal point motion
  36.  * operations (movePointLeft and movePointRight) return a BigDecimal created
  37.  * from the operand by moving the decimal point a specified distance in the
  38.  * specified direction; that is, they change a number's value without affecting
  39.  * its precision.
  40.  *
  41.  * @see BigInteger
  42.  * @version     1.12, 98/03/18
  43.  * @author      Josh Bloch
  44.  */
  45. public class BigDecimal extends Number implements Comparable {
  46.     private BigInteger intVal;
  47.     private int           scale = 0;
  48.  
  49.     /* Appease the serialization gods */
  50.     private static final long serialVersionUID = 6108874887143696463L;
  51.  
  52.     // Constructors
  53.  
  54.     /**
  55.      * Constructs a BigDecimal from a string containing an optional minus
  56.      * sign followed by a sequence of zero or more decimal digits, optionally
  57.      * followed by a fraction, which consists of a decimal point followed by
  58.      * zero or more decimal digits.  The string must contain at least one
  59.      * digit in the integer or fractional part.  The scale of the resulting
  60.      * BigDecimal will be the number of digits to the right of the decimal
  61.      * point in the string, or 0 if the string contains no decimal point.
  62.      * The character-to-digit mapping is provided by Character.digit.
  63.      * Any extraneous characters (including whitespace) will result in
  64.      * a NumberFormatException.
  65.      */
  66.     public BigDecimal(String val) throws NumberFormatException {
  67.     int pointPos = val.indexOf('.');
  68.     if (pointPos == -1) {             /* e.g. "123" */
  69.         intVal = new BigInteger(val);
  70.     } else if (pointPos == val.length()-1) { /* e.g. "123." */
  71.         intVal = new BigInteger(val.substring(0, val.length()-1));
  72.     } else {    /* Fraction part exists */
  73.         String fracString = val.substring(pointPos+1);
  74.         scale = fracString.length();
  75.         BigInteger fraction =  new BigInteger(fracString);
  76.         if (fraction.signum() < 0)         /* ".-123" illegal! */
  77.         throw new NumberFormatException();
  78.  
  79.         if (pointPos==0) {             /* e.g.  ".123" */
  80.         intVal = fraction;
  81.         } else if (val.charAt(0)=='-' && pointPos==1) {
  82.         intVal = fraction.negate();     /* e.g. "-.123" */
  83.         } else  {                 /* e.g. "-123.456" */
  84.         String intString = val.substring(0, pointPos);
  85.         BigInteger intPart = new BigInteger(intString);
  86.         if (val.charAt(0) == '-')
  87.             fraction = fraction.negate();
  88.         intVal = timesTenToThe(intPart, scale).add(fraction);
  89.         }
  90.     }
  91.     }
  92.  
  93.     /**
  94.      * Translates a double into a BigDecimal.  The scale of the BigDecimal
  95.      * is the smallest value such that (10**scale * val) is an integer.
  96.      * A double whose value is -infinity, +infinity or NaN will result in a
  97.      * NumberFormatException.
  98.      */
  99.     public BigDecimal(double val) throws NumberFormatException{
  100.     if (Double.isInfinite(val) || Double.isNaN(val))
  101.         throw new NumberFormatException("Infinite or NaN");
  102.  
  103.     /*
  104.      * Translate the double into sign, exponent and mantissa, according
  105.      * to the formulae in JLS, Section 20.10.22.
  106.      */
  107.     long valBits = Double.doubleToLongBits(val);
  108.     int sign = ((valBits >> 63)==0 ? 1 : -1);
  109.     int exponent = (int) ((valBits >> 52) & 0x7ffL);
  110.     long mantissa = (exponent==0 ? (valBits & ((1L<<52) - 1)) << 1
  111.                      : (valBits & ((1L<<52) - 1)) | (1L<<52));
  112.     exponent -= 1075;
  113.     /* At this point, val == sign * mantissa * 2**exponent */
  114.  
  115.     /*
  116.      * Special case zero to to supress nonterminating normalization
  117.      * and bogus scale calculation.
  118.      */
  119.     if (mantissa == 0) {
  120.         intVal = BigInteger.valueOf(0);
  121.         return;
  122.     }
  123.  
  124.     /* Normalize */
  125.     while((mantissa & 1) == 0) {    /*  i.e., Mantissa is even */
  126.         mantissa >>= 1;
  127.         exponent++;
  128.     }
  129.  
  130.     /* Calculate intVal and scale */
  131.     intVal = BigInteger.valueOf(sign*mantissa);
  132.     if (exponent < 0) {
  133.         intVal = intVal.multiply(BigInteger.valueOf(5).pow(-exponent));
  134.         scale = -exponent;
  135.     } else if (exponent > 0) {
  136.         intVal = intVal.multiply(BigInteger.valueOf(2).pow(exponent));
  137.     }
  138.     }
  139.  
  140.     /**
  141.      * Translates a BigInteger into a BigDecimal.  The scale of the BigDecimal
  142.      * is zero.
  143.      */
  144.     public BigDecimal(BigInteger val) {
  145.     intVal = val;
  146.     }
  147.  
  148.     /**
  149.      * Translates a BigInteger and a scale into a BigDecimal.  The value
  150.      * of the BigDecimal is (BigInteger/10**scale).  A negative scale
  151.      * will result in a NumberFormatException.
  152.      */
  153.     public BigDecimal(BigInteger val, int scale) throws NumberFormatException {
  154.     if (scale < 0)
  155.         throw new NumberFormatException("Negative scale");
  156.  
  157.     intVal = val;
  158.     this.scale = scale;
  159.     }
  160.  
  161.  
  162.     // Static Factory Methods
  163.  
  164.     /**
  165.      * Returns a BigDecimal with a value of (val/10**scale).  This factory
  166.      * is provided in preference to a (long) constructor because it allows
  167.      * for reuse of frequently used BigDecimals (like 0 and 1), obviating
  168.      * the need for exported constants.  A negative scale will result in a
  169.      * NumberFormatException.
  170.      */
  171.     public static BigDecimal valueOf(long val, int scale)
  172.         throws NumberFormatException {
  173.     return new BigDecimal(BigInteger.valueOf(val), scale);
  174.     }
  175.  
  176.     /**
  177.      * Returns a BigDecimal with the given value and a scale of zero.
  178.      * This factory is provided in preference to a (long) constructor
  179.      * because it allows for reuse of frequently used BigDecimals (like
  180.      * 0 and 1), obviating the need for exported constants.
  181.      */
  182.     public static BigDecimal valueOf(long val) {
  183.     return valueOf(val, 0);
  184.     }
  185.  
  186.  
  187.     // Arithmetic Operations
  188.  
  189.     /**
  190.      * Returns a BigDecimal whose value is (this + val), and whose scale is
  191.      * MAX(this.scale(), val.scale).
  192.      */
  193.     public BigDecimal add(BigDecimal val){
  194.     BigDecimal arg[] = new BigDecimal[2];
  195.     arg[0] = this;    arg[1] = val;
  196.     matchScale(arg);
  197.     return new BigDecimal(arg[0].intVal.add(arg[1].intVal), arg[0].scale);
  198.     }
  199.  
  200.     /**
  201.      * Returns a BigDecimal whose value is (this - val), and whose scale is
  202.      * MAX(this.scale(), val.scale).
  203.      */
  204.     public BigDecimal subtract(BigDecimal val){
  205.     BigDecimal arg[] = new BigDecimal[2];
  206.     arg[0] = this;    arg[1] = val;
  207.     matchScale(arg);
  208.     return new BigDecimal(arg[0].intVal.subtract(arg[1].intVal),
  209.                   arg[0].scale);
  210.     }
  211.  
  212.     /**
  213.      * Returns a BigDecimal whose value is (this * val), and whose scale is
  214.      * this.scale() + val.scale.
  215.      */
  216.     public BigDecimal multiply(BigDecimal val){
  217.     return new BigDecimal(intVal.multiply(val.intVal), scale+val.scale);
  218.     }
  219.  
  220.     /**
  221.      * Returns a BigDecimal whose value is (this / val), and whose scale
  222.      * is as specified.  If rounding must be performed to generate a
  223.      * result with the given scale, the specified rounding mode is
  224.      * applied.  Throws an ArithmeticException if val == 0, scale < 0,
  225.      * or the rounding mode is ROUND_UNNECESSARY and the specified scale
  226.      * is insufficient to represent the result of the division exactly.
  227.      * Throws an IllegalArgumentException if roundingMode does not
  228.      * represent a valid rounding mode.
  229.      */
  230.     public BigDecimal divide(BigDecimal val, int scale, int roundingMode)
  231.         throws ArithmeticException, IllegalArgumentException {
  232.     if (scale < 0)
  233.         throw new ArithmeticException("Negative scale");
  234.     if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
  235.         throw new IllegalArgumentException("Invalid rounding mode");
  236.  
  237.     /*
  238.      * Rescale dividend or divisor (whichever can be "upscaled" to
  239.      * produce correctly scaled quotient).
  240.      */
  241.     BigDecimal dividend, divisor;
  242.     if (scale + val.scale >= this.scale) {
  243.         dividend = this.setScale(scale + val.scale);
  244.         divisor = val;
  245.     } else {
  246.         dividend = this;
  247.         divisor = val.setScale(this.scale - scale);
  248.     }
  249.  
  250.     /* Do the division and return result if it's exact */
  251.     BigInteger i[] = dividend.intVal.divideAndRemainder(divisor.intVal);
  252.     BigInteger q = i[0], r = i[1];
  253.     if (r.signum() == 0)
  254.         return new BigDecimal(q, scale);
  255.     else if (roundingMode == ROUND_UNNECESSARY) /* Rounding prohibited */
  256.         throw new ArithmeticException("Rounding necessary");
  257.  
  258.     /* Round as appropriate */
  259.     int signum = dividend.signum() * divisor.signum(); /* Sign of result */
  260.     boolean increment;
  261.     if (roundingMode == ROUND_UP) {            /* Away from zero */
  262.         increment = true;
  263.     } else if (roundingMode == ROUND_DOWN) {    /* Towards zero */
  264.         increment = false;
  265.     } else if (roundingMode == ROUND_CEILING) { /* Towards +infinity */
  266.         increment = (signum > 0);
  267.     } else if (roundingMode == ROUND_FLOOR) {   /* Towards -infinity */
  268.         increment = (signum < 0);
  269.     } else { /* Remaining modes based on nearest-neighbor determination */
  270.         int cmpFracHalf = r.abs().multiply(BigInteger.valueOf(2)).
  271.                      compareTo(divisor.intVal.abs());
  272.         if (cmpFracHalf < 0) {       /* We're closer to higher digit */
  273.         increment = false;
  274.         } else if (cmpFracHalf > 0) {  /* We're closer to lower digit */
  275.         increment = true;
  276.         } else {                /* We're dead-center */
  277.         if (roundingMode == ROUND_HALF_UP)
  278.             increment = true;
  279.         else if (roundingMode == ROUND_HALF_DOWN)
  280.             increment = false;
  281.         else  /* roundingMode == ROUND_HALF_EVEN */
  282.             increment = q.testBit(0);    /* true iff q is odd */
  283.         }
  284.     }
  285.     return (increment
  286.         ? new BigDecimal(q.add(BigInteger.valueOf(signum)), scale)
  287.         : new BigDecimal(q, scale));
  288.     }
  289.  
  290.     /**
  291.      * Returns a BigDecimal whose value is (this / val), and whose scale
  292.      * is this.scale().  If rounding must be performed to generate a
  293.      * result with the given scale, the specified rounding mode is
  294.      * applied.  Throws an ArithmeticException if val == 0.  Throws
  295.      * an IllegalArgumentException if roundingMode does not represent a
  296.      * valid rounding mode.
  297.      */
  298.     public BigDecimal divide(BigDecimal val, int roundingMode)
  299.     throws ArithmeticException, IllegalArgumentException{
  300.         return this.divide(val, scale, roundingMode);
  301.     }
  302.  
  303.    /**
  304.     * Returns a BigDecimal whose value is the absolute value of this
  305.     * number, and whose scale is this.scale().
  306.     */
  307.     public BigDecimal abs(){
  308.     return (signum() < 0 ? negate() : this);
  309.     }
  310.  
  311.     /**
  312.      * Returns a BigDecimal whose value is -1 * this, and whose scale is
  313.      * this.scale().
  314.      */
  315.     public BigDecimal negate(){
  316.     return new BigDecimal(intVal.negate(), scale);
  317.     }
  318.  
  319.     /**
  320.      * Returns the signum function of this number (i.e., -1, 0 or 1 as
  321.      * the value of this number is negative, zero or positive).
  322.      */
  323.     public int signum(){
  324.     return intVal.signum();
  325.     }
  326.  
  327.     /**
  328.      * Returns the scale of this number.
  329.      */
  330.     public int scale(){
  331.     return scale;
  332.     }
  333.  
  334.  
  335.     // Rounding Modes
  336.  
  337.     /**
  338.      * Always increment the digit prior to a non-zero discarded fraction.
  339.      * Note that this rounding mode never decreases the magnitude.
  340.      * (Rounds away from zero.)
  341.      */
  342.     public final static int ROUND_UP =          0;
  343.  
  344.     /**
  345.      * Never increment the digit prior to a discarded fraction (i.e.,
  346.      * truncate).  Note that this rounding mode never increases the magnitude.
  347.      * (Rounds towards zero.)
  348.      */
  349.     public final static int ROUND_DOWN =      1;
  350.  
  351.     /**
  352.      * If the BigDecimal is positive, behave as for ROUND_UP; if negative,
  353.      * behave as for ROUND_DOWN.  Note that this rounding mode never decreases
  354.      * the value.  (Rounds towards positive infinity.)
  355.      */
  356.     public final static int ROUND_CEILING =      2;
  357.  
  358.     /**
  359.      * If the BigDecimal is positive, behave as for ROUND_DOWN; if negative
  360.      * behave as for ROUND_UP.  Note that this rounding mode never increases
  361.      * the value.  (Rounds towards negative infinity.)
  362.      */
  363.     public final static int ROUND_FLOOR =      3;
  364.  
  365.     /**
  366.      * Behave as for ROUND_UP if the discarded fraction is >= .5; otherwise,
  367.      * behave as for ROUND_DOWN.  (Rounds towards "nearest neighbor" unless
  368.      * both neighbors are equidistant, in which case rounds up.)
  369.      */
  370.     public final static int ROUND_HALF_UP =      4;
  371.  
  372.     /**
  373.      * Behave as for ROUND_UP if the discarded fraction is > .5; otherwise,
  374.      * behave as for ROUND_DOWN.   (Rounds towards "nearest neighbor" unless
  375.      * both neighbors are equidistant, in which case rounds down.)
  376.      */
  377.     public final static int ROUND_HALF_DOWN =      5;
  378.  
  379.     /**
  380.      * Behave as for ROUND_HALF_UP if the digit to the left of the discarded
  381.      * fraction is odd; behave as for ROUND_HALF_DOWN if it's even.  (Rounds
  382.      * towards the "nearest neighbor" unless both neighbors are equidistant,
  383.      * in which case, rounds towards the even neighbor.)
  384.      */
  385.     public final static int ROUND_HALF_EVEN =      6;
  386.  
  387.     /**
  388.      * This "pseudo-rounding-mode" is actually an assertion that the requested
  389.      * operation has an exact result, hence no rounding is necessary.  If this
  390.      * rounding mode is specified on an operation that yields an inexact result,
  391.      * an arithmetic exception is thrown.
  392.      */
  393.     public final static int ROUND_UNNECESSARY =  7;
  394.  
  395.  
  396.     // Scaling/Rounding Operations
  397.  
  398.     /**
  399.      * Returns a BigDecimal whose scale is the specified value, and whose
  400.      * integer value is determined by multiplying or dividing this BigDecimal's
  401.      * integer value by the appropriate power of ten to maintain the overall
  402.      * value.  If the scale is reduced by the operation, the integer value
  403.      * must be divided (rather than multiplied), and precision may be lost;
  404.      * in this case, the specified rounding mode is applied to the division.
  405.      * Throws an ArithmeticException if scale is negative, or the rounding
  406.      * mode is ROUND_UNNECESSARY and it is impossible to perform the
  407.      * specified scaling operation without loss of precision.  Throws an
  408.      * IllegalArgumentException if roundingMode does not represent a valid
  409.      * rounding mode.
  410.      */
  411.     public BigDecimal setScale(int scale, int roundingMode)
  412.     throws ArithmeticException, IllegalArgumentException {
  413.     if (scale < 0)
  414.         throw new ArithmeticException("Negative scale");
  415.     if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
  416.         throw new IllegalArgumentException("Invalid rounding mode");
  417.  
  418.     /* Handle the easy cases */
  419.     if (scale == this.scale)
  420.         return this;
  421.     else if (scale > this.scale)
  422.         return new BigDecimal(timesTenToThe(intVal, scale-this.scale),
  423.                   scale);
  424.     else /* scale < this.scale */
  425.         return divide(valueOf(1), scale, roundingMode);
  426.     }
  427.  
  428.     /**
  429.      * Returns a BigDecimal whose scale is the specified value, and whose
  430.      * value is exactly equal to this number's.  Throws an ArithmeticException
  431.      * if this is not possible.  This call is typically used to increase
  432.      * the scale, in which case it is guaranteed that there exists a BigDecimal
  433.      * of the specified scale and the correct value.  The call can also be used
  434.      * to reduce the scale if the caller knows that the number has sufficiently
  435.      * many zeros at the end of its fractional part (i.e., factors of ten in
  436.      * its integer value) to allow for the rescaling without loss of precision.
  437.      * Note that this call returns the same result as the two argument version
  438.      * of setScale, but saves the caller the trouble of specifying a rounding
  439.      * mode in cases where it is irrelevant.
  440.      */
  441.     public BigDecimal setScale(int scale)
  442.     throws ArithmeticException, IllegalArgumentException
  443.     {
  444.     return setScale(scale, ROUND_UNNECESSARY);
  445.     }
  446.  
  447.  
  448.     // Decimal Point Motion Operations
  449.  
  450.     /**
  451.      * Returns a BigDecimal which is equivalent to this one with the decimal
  452.      * point moved n places to the left.  If n is non-negative, the call merely
  453.      * adds n to the scale.  If n is negative, the call is equivalent to
  454.      * movePointRight(-n).  (The BigDecimal returned by this call has value
  455.      * (this * 10**-n) and scale MAX(this.scale()+n, 0).)
  456.      */
  457.     public BigDecimal movePointLeft(int n){
  458.     return (n>=0 ? new BigDecimal(intVal, scale+n) : movePointRight(-n));
  459.     }
  460.  
  461.     /**
  462.      * Moves the decimal point the specified number of places to the right.
  463.      * If this number's scale is >= n, the call merely subtracts n from the
  464.      * scale; otherwise, it sets the scale to zero, and multiplies the integer
  465.      * value by 10 ** (n - this.scale).  If n is negative, the call is
  466.      * equivalent to movePointLeft(-n). (The BigDecimal returned by this call
  467.      * has value (this * 10**n) and scale MAX(this.scale()-n, 0).)
  468.      */
  469.     public BigDecimal movePointRight(int n){
  470.     return (scale >= n ? new BigDecimal(intVal, scale-n)
  471.                    : new BigDecimal(timesTenToThe(intVal, n-scale),0));
  472.     }
  473.  
  474.     // Comparison Operations
  475.  
  476.     /**
  477.      * Returns -1, 0 or 1 as this number is less than, equal to, or greater
  478.      * than val.  Two BigDecimals that are equal in value but have a
  479.      * different scale (e.g., 2.0, 2.00) are considered equal by this method.
  480.      * This method is provided in preference to individual methods for each
  481.      * of the six boolean comparison operators (<, ==, >, >=, !=,
  482.      * <=).  The suggested idiom for performing these comparisons is:
  483.      * (x.compareTo(y) <op> 0), where <op> is one of the six
  484.      * comparison operators.
  485.      */
  486.     public int compareTo(BigDecimal val){
  487.     /* Optimization: would run fine without the next three lines */
  488.     int sigDiff = signum() - val.signum();
  489.     if (sigDiff != 0)
  490.         return (sigDiff > 0 ? 1 : -1);
  491.  
  492.     /* If signs match, scale and compare intVals */
  493.     BigDecimal arg[] = new BigDecimal[2];
  494.     arg[0] = this;    arg[1] = val;
  495.     matchScale(arg);
  496.     return arg[0].intVal.compareTo(arg[1].intVal);
  497.     }
  498.  
  499.     /**
  500.      * Compares this BigDecimal to another Object.  If the Object is a
  501.      * BigDecimal, this function behaves like
  502.      * <code>compareTo(BigDecimal)</code>.  Otherwise, it throws a
  503.      * <code>ClassCastException</code> (as BigDecimals are comparable
  504.      * only to other BigDecimals).
  505.      *
  506.      * @param   o the <code>Object</code> to be compared.
  507.      * @return  the value <code>0</code> if the argument is a BigDecimal
  508.      *        numerically equal to this BigDecimal; a value less than
  509.      *        <code>0</code> if the argument is a BigDecimal numerically
  510.      *        greater than this BigDecimal; and a value greater than
  511.      *        <code>0</code> if the argument is a BigDecimal numerically
  512.      *        less than this BigDecimal.
  513.      * @exception <code>ClassCastException</code> if the argument is not a
  514.      *          <code>BigDecimal</code>. 
  515.      * @see     java.lang.Comparable
  516.      * @since   JDK1.2
  517.      */
  518.     public int compareTo(Object o) {
  519.     return compareTo((BigDecimal)o);
  520.     }
  521.  
  522.     /**
  523.      * Returns true iff x is a BigDecimal whose value is equal to this number.
  524.      * This method is provided so that BigDecimals can be used as hash keys.
  525.      * Unlike compareTo, this method considers two BigDecimals equal only
  526.      * if they are equal in value and scale.
  527.      */
  528.     public boolean equals(Object x){
  529.     if (!(x instanceof BigDecimal))
  530.         return false;
  531.     BigDecimal xDec = (BigDecimal) x;
  532.  
  533.     return scale == xDec.scale && intVal.equals(xDec.intVal);
  534.     }
  535.  
  536.     /**
  537.      * Returns the BigDecimal whose value is the lesser of this and val.
  538.      * If the values are equal (as defined by the compareTo operator),
  539.      * either may be returned.
  540.      */
  541.     public BigDecimal min(BigDecimal val){
  542.     return (compareTo(val)<0 ? this : val);
  543.     }
  544.  
  545.     /**
  546.      * Returns the BigDecimal whose value is the greater of this and val.
  547.      * If the values are equal (as defined by the compareTo operator),
  548.      * either may be returned.
  549.      */
  550.     public BigDecimal max(BigDecimal val){
  551.     return (compareTo(val)>0 ? this : val);
  552.     }
  553.  
  554.  
  555.     // Hash Function
  556.  
  557.     /**
  558.      * Computes a hash code for this object.  Note that two BigDecimals
  559.      * that are numerically equal but differ in scale (e.g., 2.0, 2.00) will
  560.      * not generally have the same hash code.
  561.      */
  562.     public int hashCode(){
  563.     return 31*intVal.hashCode() + scale;
  564.     }
  565.  
  566.     // Format Converters
  567.  
  568.     /**
  569.      * Returns the string representation of this number.  The digit-to-
  570.      * character mapping provided by Character.forDigit is used.  The minus
  571.      * sign and decimal point are used to indicate sign and scale.  (This
  572.      * representation is compatible with the (String, int) constructor.)
  573.      */
  574.     public String toString(){
  575.     if (scale == 0)    /* No decimal point */
  576.         return intVal.toString();
  577.  
  578.     /* Insert decimal point */
  579.     StringBuffer buf;
  580.     String intString = intVal.abs().toString();
  581.     int signum = signum();
  582.     int insertionPoint = intString.length() - scale;
  583.     if (insertionPoint == 0) {  /* Point goes right before intVal */
  584.         return (signum<0 ? "-0." : "0.") + intString;
  585.     } else if (insertionPoint > 0) { /* Point goes inside intVal */
  586.         buf = new StringBuffer(intString);
  587.         buf.insert(insertionPoint, '.');
  588.         if (signum < 0)
  589.         buf.insert(0, '-');
  590.     } else { /* We must insert zeros between point and intVal */
  591.         buf = new StringBuffer(3-insertionPoint + intString.length());
  592.         buf.append(signum<0 ? "-0." : "0.");
  593.         for (int i=0; i<-insertionPoint; i++)
  594.         buf.append('0');
  595.         buf.append(intString);
  596.     }
  597.     return buf.toString();
  598.     }
  599.  
  600.     /**
  601.      * Converts this number to a BigInteger.  Standard narrowing primitive
  602.      * conversion as per The Java Language Specification.  In particular,
  603.      * note that any fractional part of this number will be truncated.
  604.      */
  605.     public BigInteger toBigInteger(){
  606.     return (scale==0 ? intVal
  607.              : intVal.divide(BigInteger.valueOf(10).pow(scale)));
  608.     }
  609.  
  610.     /**
  611.      * Converts this number to an int.  Standard narrowing primitive conversion
  612.      * as per The Java Language Specification.  In particular, note that any
  613.      * fractional part of this number will be truncated.
  614.      */
  615.     public int intValue(){
  616.     return toBigInteger().intValue();
  617.     }
  618.  
  619.     /**
  620.      * Converts this number to a long.  Standard narrowing primitive conversion
  621.      * as per The Java Language Specification.  In particular, note that any
  622.      * fractional part of this number will be truncated.
  623.      */
  624.     public long longValue(){
  625.     return toBigInteger().longValue();
  626.     }
  627.  
  628.     /**
  629.      * Converts this number to a float.  Similar to the double-to-float
  630.      * narrowing primitive conversion defined in The Java Language
  631.      * Specification: if the number has too great a magnitude to represent
  632.      * as a float, it will be converted to infinity or negative infinity,
  633.      * as appropriate.
  634.      */
  635.     public float floatValue(){
  636.     /* Somewhat inefficient, but guaranteed to work. */
  637.     return Float.valueOf(this.toString()).floatValue();
  638.     }
  639.  
  640.     /**
  641.      * Converts the number to a double.  Similar to the double-to-float
  642.      * narrowing primitive conversion defined in The Java Language
  643.      * Specification: if the number has too great a magnitude to represent
  644.      * as a double, it will be converted to infinity or negative infinity,
  645.      * as appropriate.
  646.      */
  647.     public double doubleValue(){
  648.     /* Somewhat inefficient, but guaranteed to work. */
  649.     return Double.valueOf(this.toString()).doubleValue();
  650.     }
  651.  
  652.  
  653.     // Private "Helper" Methods
  654.  
  655.     /* Returns (a * 10^b) */
  656.     private static BigInteger timesTenToThe(BigInteger a, int b) {
  657.     return a.multiply(BigInteger.valueOf(10).pow(b));
  658.     }
  659.  
  660.     /*
  661.      * If the scales of val[0] and val[1] differ, rescale (non-destructively)
  662.      * the lower-scaled BigDecimal so they match.
  663.      */
  664.     private static void matchScale(BigDecimal[] val) {
  665.     if (val[0].scale < val[1].scale)
  666.         val[0] = val[0].setScale(val[1].scale);
  667.     else if (val[1].scale < val[0].scale)
  668.         val[1] = val[1].setScale(val[0].scale);
  669.     }
  670. }
  671.