home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 February / VPR9802A.ISO / APP_DEMO / VC / MAIN.BIN / BigDecimal.java < prev    next >
Text File  |  1997-10-27  |  24KB  |  652 lines

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