< prev index next >

src/java.base/share/classes/java/math/BigDecimal.java

Print this page




 329      */
 330     public static final BigDecimal ZERO =
 331         ZERO_THROUGH_TEN[0];
 332 
 333     /**
 334      * The value 1, with a scale of 0.
 335      *
 336      * @since  1.5
 337      */
 338     public static final BigDecimal ONE =
 339         ZERO_THROUGH_TEN[1];
 340 
 341     /**
 342      * The value 10, with a scale of 0.
 343      *
 344      * @since  1.5
 345      */
 346     public static final BigDecimal TEN =
 347         ZERO_THROUGH_TEN[10];
 348 










 349     // Constructors
 350 
 351     /**
 352      * Trusted package private constructor.
 353      * Trusted simply means if val is INFLATED, intVal could not be null and
 354      * if intVal is null, val could not be INFLATED.
 355      */
 356     BigDecimal(BigInteger intVal, long val, int scale, int prec) {
 357         this.scale = scale;
 358         this.precision = prec;
 359         this.intCompact = val;
 360         this.intVal = intVal;
 361     }
 362 
 363     /**
 364      * Translates a character array representation of a
 365      * {@code BigDecimal} into a {@code BigDecimal}, accepting the
 366      * same sequence of characters as the {@link #BigDecimal(String)}
 367      * constructor, while allowing a sub-array to be specified.
 368      *


1976      *         initial element and the remainder is the final element.
1977      * @throws ArithmeticException if {@code divisor==0}
1978      * @throws ArithmeticException if the result is inexact but the
1979      *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
1980      *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
1981      *         require a precision of more than {@code mc.precision} digits.
1982      * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
1983      * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
1984      * @since  1.5
1985      */
1986     public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
1987         if (mc.precision == 0)
1988             return divideAndRemainder(divisor);
1989 
1990         BigDecimal[] result = new BigDecimal[2];
1991         BigDecimal lhs = this;
1992 
1993         result[0] = lhs.divideToIntegralValue(divisor, mc);
1994         result[1] = lhs.subtract(result[0].multiply(divisor));
1995         return result;


























































































































































































































1996     }
1997 
1998     /**
1999      * Returns a {@code BigDecimal} whose value is
2000      * <code>(this<sup>n</sup>)</code>, The power is computed exactly, to
2001      * unlimited precision.
2002      *
2003      * <p>The parameter {@code n} must be in the range 0 through
2004      * 999999999, inclusive.  {@code ZERO.pow(0)} returns {@link
2005      * #ONE}.
2006      *
2007      * Note that future releases may expand the allowable exponent
2008      * range of this method.
2009      *
2010      * @param  n power to raise this {@code BigDecimal} to.
2011      * @return <code>this<sup>n</sup></code>
2012      * @throws ArithmeticException if {@code n} is out of range.
2013      * @since  1.5
2014      */
2015     public BigDecimal pow(int n) {




 329      */
 330     public static final BigDecimal ZERO =
 331         ZERO_THROUGH_TEN[0];
 332 
 333     /**
 334      * The value 1, with a scale of 0.
 335      *
 336      * @since  1.5
 337      */
 338     public static final BigDecimal ONE =
 339         ZERO_THROUGH_TEN[1];
 340 
 341     /**
 342      * The value 10, with a scale of 0.
 343      *
 344      * @since  1.5
 345      */
 346     public static final BigDecimal TEN =
 347         ZERO_THROUGH_TEN[10];
 348 
 349     /**
 350      * The value 0.1, with a scale of 1.
 351      */
 352     private static final BigDecimal ONE_TENTH = valueOf(1L, 1);
 353 
 354     /**
 355      * The value 0.5, with a scale of 1.
 356      */
 357     private static final BigDecimal ONE_HALF = valueOf(5L, 1);
 358 
 359     // Constructors
 360 
 361     /**
 362      * Trusted package private constructor.
 363      * Trusted simply means if val is INFLATED, intVal could not be null and
 364      * if intVal is null, val could not be INFLATED.
 365      */
 366     BigDecimal(BigInteger intVal, long val, int scale, int prec) {
 367         this.scale = scale;
 368         this.precision = prec;
 369         this.intCompact = val;
 370         this.intVal = intVal;
 371     }
 372 
 373     /**
 374      * Translates a character array representation of a
 375      * {@code BigDecimal} into a {@code BigDecimal}, accepting the
 376      * same sequence of characters as the {@link #BigDecimal(String)}
 377      * constructor, while allowing a sub-array to be specified.
 378      *


1986      *         initial element and the remainder is the final element.
1987      * @throws ArithmeticException if {@code divisor==0}
1988      * @throws ArithmeticException if the result is inexact but the
1989      *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
1990      *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
1991      *         require a precision of more than {@code mc.precision} digits.
1992      * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
1993      * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
1994      * @since  1.5
1995      */
1996     public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
1997         if (mc.precision == 0)
1998             return divideAndRemainder(divisor);
1999 
2000         BigDecimal[] result = new BigDecimal[2];
2001         BigDecimal lhs = this;
2002 
2003         result[0] = lhs.divideToIntegralValue(divisor, mc);
2004         result[1] = lhs.subtract(result[0].multiply(divisor));
2005         return result;
2006     }
2007 
2008 
2009     /**
2010      * Returns an approximation to the square root of {@code this}
2011      * with rounding according to the context settings.
2012      *
2013      * <p>The preferred scale of the returned result is equal to
2014      * {@code floor(this.scale()/2.0)}. The value of the returned
2015      * result is always within one ulp of the exact decimal value for
2016      * the precision in question.  If the rounding mode is {@link
2017      * RoundingMode#HALF_UP HALF_UP}, {@link RoundingMode#HALF_DOWN
2018      * HALF_DOWN}, or {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
2019      * result is within one half an ulp of the exact decimal value.
2020      *
2021      * <p>Special case:
2022      * <ul>
2023      * <li> The square root of a number numerically equal to {@code
2024      * ZERO} is equal to {@code ZERO}.
2025      * </ul>
2026      *
2027      * @param mc the context to use.
2028      * @return the square root of {@code this}.
2029      * @throws ArithmeticException if {@code this} is less than zero.
2030      * @throws ArithmeticException if an exact result is requested
2031      * ({@code mc.getPrecision()==0}) and there is no finite decimal
2032      * expansion of the exact result
2033      * @throws ArithmeticException if
2034      * {@code (mc.getRoundingMode()==RoundingMode.UNNECESSARY}) and
2035      * the exact result cannot fit in {@code mc.getPrecision()}
2036      * digits.
2037      * @since  9
2038      */
2039     public BigDecimal sqrt(MathContext mc) {
2040         int signum = signum();
2041         if (signum == 1) {
2042             /*
2043              * The following code draws on the algorithm presented in
2044              * "Properly Rounded Variable Precision Square Root," Hull and
2045              * Abrham, ACM Transactions on Mathematical Software, Vol 11,
2046              * No. 3, September 1985, Pages 229-237.
2047              *
2048              * The BigDecimal computational model differs from the one
2049              * presented in the paper in several ways: first BigDecimal
2050              * numbers aren't necessarily normalized, second many more
2051              * rounding modes are supported, including UNNECESSARY, and
2052              * exact results can be requested.
2053              *
2054              * The main steps of the algorithm below are as follow, first
2055              * argument reduce the value to the numerical range [1, 10)
2056              * using the following relations:
2057              *
2058              * x = y * 10 ^ exp
2059              * sqrt(x) = sqrt(y) * 10^(exp / 2) if exp is even
2060              * sqrt(x) = sqrt(y/10) * 10 ^((exp+1)/2) is exp is odd
2061              *
2062              * Then use Newton's iteration on the reduced value to compute
2063              * the numerical digits of the desired result.
2064              *
2065              * Finally, scale back to the desired exponent range and
2066              * perform any adjustment to get the preferred scale in the
2067              * representation.
2068              */
2069 
2070             // The code below favors relative simplicity over checking
2071             // for special cases that could run faster.
2072 
2073             BigDecimal zeroWithFinalPreferredScale = valueOf(0L, this.scale()/2);
2074 
2075             // First phase of numerical normalization, strip trailing
2076             // zeros and check for even powers of 10.
2077             BigDecimal stripped = this.stripTrailingZeros();
2078             int strippedScale = stripped.scale();
2079 
2080             // Numerically, sqrt(10^2N) = 10^N
2081             if (BigInteger.ONE.equals(stripped.unscaledValue()) &&
2082                 strippedScale % 2 == 0) {
2083                 BigDecimal result = valueOf(1L, strippedScale/2);
2084                 // Adjust to requested precision and preferred scale as possible
2085                 return result.add(zeroWithFinalPreferredScale, mc);
2086             }
2087 
2088             System.out.println("\tStarting: " + this); // DEBUG
2089             System.out.println("\tStripped: " + stripped); // DEBUG
2090 
2091 
2092             // After stripTrailingZeros, the representation is normalized as
2093             //
2094             // unscaledValue * 10^(-scale)
2095             //
2096             // where unscaledValue is an integer with the mimimum
2097             // precision for the cohort of the numerical value. To
2098             // allow binary floating-point hardware to be used to get
2099             // approximately a 15 digit approximation to the square
2100             // root, it is helpful to instead normalize this as so
2101             // that the significand portion is to right of the decimal
2102             // point, roughly:
2103             //
2104             // (unscaledValue * (10^-precision) * 10^(-scale)) * (10^precision)
2105             //
2106             // so that
2107             //
2108             // sqrt(unscaledValue * (10^-precision) * 10^(-scale) * (10^precision)) =
2109             //
2110             // sqrt(unscaledValue * (10^-precision) * 10^(-scale)) * 10^(precision/2)
2111             //
2112             // Therefore, this adjustment occurs for by 10^-precision is precision is even or 
2113             // (adjust as needed, +/-1
2114             //
2115             // (A double value might have as much as 17 decimal digits
2116             // of precision; it depends on the relative density of
2117             // binary and decimal numbers at different points of the
2118             // number line.)
2119 
2120             // Now the precision / scale adjustment
2121             int scaleAdjust = 0;
2122             int scale = stripped.scale() - stripped.precision() + 1;
2123             if (scale % 2 == 0) {
2124                 scaleAdjust = scale;
2125             } else {
2126                 scaleAdjust = scale - 1;
2127                 stripped = stripped.divide(TEN);
2128             }
2129 
2130             // At least document potential exponent overflow issues here???
2131             BigDecimal working = stripped.scaleByPowerOfTen(scaleAdjust);
2132             System.out.println("\tWorking2: " + working + "\tscale: " + working.scale()); // DEBUG
2133 
2134             // Verify 1 <= working < 10 (verify range)
2135             assert working.compareTo(ONE) >= 0 && working.compareTo(TEN) < 0;
2136 
2137             // Use good ole' Math.sqrt to get the initial guess for the
2138             // Newton iteration, good to at least 15 decimal digits.
2139             BigDecimal guess = new BigDecimal(Math.sqrt(working.doubleValue()));
2140             int guessPrecision = 15;
2141             int originalPrecision = mc.getPrecision();
2142             int targetPrecision;
2143             // If an exact value is requested, it must only need about
2144             // half of the input digits to represent since multiplying
2145             // two N digit numbers yield a 2N-1 or 2N digit result.
2146             if (originalPrecision == 0) {
2147                 targetPrecision = stripped.precision()/2 + 1;
2148             } else {
2149                 targetPrecision = originalPrecision;
2150             }
2151 
2152             // When setting the precision to use inside the Newton
2153             // iteration loop, take care to avoid the case where the
2154             // precision of the input exceeds the requested precision
2155             // and rounding the input value too soon.
2156             BigDecimal approx = guess;
2157             int workingPrecision = working.precision();
2158             do {
2159                 // If did more work, could we make sure the
2160                 // approximation was uniformly above / below the root?
2161 
2162                 System.out.println(approx); // DEBUG
2163                 int tmpPrecision = Math.max(Math.max(guessPrecision, targetPrecision + 2),
2164                                            workingPrecision);
2165                 MathContext mcTmp = new MathContext(tmpPrecision, RoundingMode.HALF_EVEN);
2166                 // approx = 0.5 * (approx + fraction / approx)
2167                 approx = ONE_HALF.multiply(approx.add(working.divide(approx, mcTmp), mcTmp));
2168                 guessPrecision *= 2;
2169             } while (guessPrecision < targetPrecision + 2);
2170 
2171             // Need additinal checking for HALF_EVEN since we are only
2172             // using two extra precision digits?
2173             BigDecimal result;
2174             RoundingMode targetRm = mc.getRoundingMode();
2175             if (targetRm == RoundingMode.UNNECESSARY || originalPrecision == 0) {
2176                 RoundingMode tmpRm =
2177                     (targetRm == RoundingMode.UNNECESSARY) ? RoundingMode.DOWN : targetRm;
2178                 MathContext mcTmp = new MathContext(targetPrecision, tmpRm);
2179                 result = approx.round(mcTmp);
2180                 result.scaleByPowerOfTen(-scaleAdjust/2);
2181                 // If result*result != the starting value numerically,
2182                 // the square root isn't exact
2183                 if (this.subtract(result.multiply(result)).compareTo(ZERO) != 0) {
2184                     throw new ArithmeticException("Computed square root not exact.");
2185                 }
2186             } else {
2187                 result = approx.round(mc);
2188                 result = result.scaleByPowerOfTen(-scaleAdjust/2);
2189             }
2190 
2191             // For now, skip the rounding up / down fix up
2192 
2193             // Read through "What every ..." for 2p + 2 discussion...
2194 
2195             // Handle 1/2 ulp, 1 ulp, and unnecessary rounding separately?
2196             // UP, DOWN,
2197             // CEILING (equiv to UP), FLOOR (equiv to DOWN), 
2198             //
2199             // HALF_UP, HALF_DOWN, HALF_EVEN -- look up 2p + 2 derivation
2200             // -- same for decimal as well as binary?
2201 
2202             // Could use direct definition to test adjacent values to
2203             // target precision -- need to lookup if Newton's iteration
2204             // converges from above or below to avoid checking three values...
2205 
2206             // Final answer: rescale fraction and then add a zero with the
2207             // preferred scale with a rounding precision equal to the
2208             // original precision.
2209             
2210             return result.add(zeroWithFinalPreferredScale,
2211                               new MathContext(originalPrecision, RoundingMode.UNNECESSARY));
2212         } else {
2213             switch (signum) {
2214             case -1:
2215                 throw new ArithmeticException("Attempted square root " + 
2216                                               "of negative BigDecimal");
2217             case 0:
2218                 return valueOf(0L, scale()/2);
2219 
2220             default:
2221                 throw new AssertionError("Bad value from signum");
2222             }
2223         }
2224     }
2225 
2226     /**
2227      * Returns a {@code BigDecimal} whose value is
2228      * <code>(this<sup>n</sup>)</code>, The power is computed exactly, to
2229      * unlimited precision.
2230      *
2231      * <p>The parameter {@code n} must be in the range 0 through
2232      * 999999999, inclusive.  {@code ZERO.pow(0)} returns {@link
2233      * #ONE}.
2234      *
2235      * Note that future releases may expand the allowable exponent
2236      * range of this method.
2237      *
2238      * @param  n power to raise this {@code BigDecimal} to.
2239      * @return <code>this<sup>n</sup></code>
2240      * @throws ArithmeticException if {@code n} is out of range.
2241      * @since  1.5
2242      */
2243     public BigDecimal pow(int n) {


< prev index next >