< 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 targetPrecision = mc.getPrecision();
2142             RoundingMode rm = mc.getRoundingMode();
2143 
2144             // When setting the precision to use inside the loop, take
2145             // care to avoid the case where the precision of the input
2146             // exceeds the requested precision and rounding the input
2147             // value too soon.
2148             BigDecimal approx = guess;
2149             int workingPrecision = working.precision();
2150             do {
2151                 System.out.println(approx); // DEBUG
2152                 int tmpPrecision = Math.max(Math.max(guessPrecision, targetPrecision + 2),
2153                                            workingPrecision);
2154                 MathContext mcTmp = new MathContext(tmpPrecision, RoundingMode.HALF_EVEN);
2155                 // approx = 0.5 * (approx + fraction / approx)
2156                 approx = ONE_HALF.multiply(approx.add(working.divide(approx, mcTmp), mcTmp));
2157                 guessPrecision *= 2;
2158             } while (guessPrecision < targetPrecision + 2);
2159             
2160             
2161             BigDecimal result = approx.round(mc);
2162 
2163             // TODO: need code for Round.UNNECESSARY. Probably also
2164             // need additinal checking for HALF_EVEN since we are only
2165             // using two extra precision digits.
2166 
2167             // For now, skip the rounding up / down fix up
2168 
2169             // Read through "What every ..." for 2p + 2 discussion...
2170 
2171             // Handle 1/2 ulp, 1 ulp, and unnecessary rounding separately?
2172             // UP, DOWN,
2173             // CEILING (equiv to UP), FLOOR (equiv to DOWN), 
2174             //
2175             // HALF_UP, HALF_DOWN, HALF_EVEN -- look up 2p + 2 derivation
2176             // -- same for decimal as well as binary?
2177 
2178             // Could use direct definition to test adjacent values to
2179             // target precision -- need to lookup if Newton's iteration
2180             // converges from above or below to avoid checking three values...
2181 
2182             // UNNECESSARY
2183 
2184             // Unnecessary rounding -- in the worst case, only need about
2185             // (1/2 + 1) digits to produce an exact output, sqrt(100) =
2186             // 10, sqrt(10_000) = 100, etc.. How to handle cases that are
2187             // powers of 10 with trailing zeros?
2188 
2189             // Normalize to a range [.1, 1] or [1, 10] -- presunmably this
2190             // is open on one end to account for exact square roots...
2191             // 
2192 
2193 
2194             // Convert to double and take double sqrt -- easy way to get
2195             // (at least) 15 digits of a decimal approximation :-)
2196 
2197             // If did more work, could make sure came in from uniformly
2198             // above / below the root?
2199 
2200             // Final answer: rescale fraction and then add a zero with the
2201             // preferred scale with a rounding precision equal to the
2202             // target precision.
2203             
2204             result = result.scaleByPowerOfTen(-scaleAdjust/2);
2205             return result.add(zeroWithFinalPreferredScale,
2206                               new MathContext(mc.getPrecision(), RoundingMode.UNNECESSARY));
2207         } else {
2208             switch (signum) {
2209             case -1:
2210                 throw new ArithmeticException("Attempted square root " + 
2211                                               "of negative BigDecimal");
2212             case 0:
2213                 return valueOf(0L, scale()/2);
2214 
2215             default:
2216                 throw new AssertionError("Bad value from signum");
2217             }
2218         }
2219     }
2220 
2221     /**
2222      * Returns a {@code BigDecimal} whose value is
2223      * <code>(this<sup>n</sup>)</code>, The power is computed exactly, to
2224      * unlimited precision.
2225      *
2226      * <p>The parameter {@code n} must be in the range 0 through
2227      * 999999999, inclusive.  {@code ZERO.pow(0)} returns {@link
2228      * #ONE}.
2229      *
2230      * Note that future releases may expand the allowable exponent
2231      * range of this method.
2232      *
2233      * @param  n power to raise this {@code BigDecimal} to.
2234      * @return <code>this<sup>n</sup></code>
2235      * @throws ArithmeticException if {@code n} is out of range.
2236      * @since  1.5
2237      */
2238     public BigDecimal pow(int n) {


< prev index next >