< 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             int preferredScale = this.scale()/2;
2074             BigDecimal zeroWithFinalPreferredScale = valueOf(0L, preferredScale);
2075 
2076             // First phase of numerical normalization, strip trailing
2077             // zeros and check for even powers of 10.
2078             BigDecimal stripped = this.stripTrailingZeros();
2079             int strippedScale = stripped.scale();
2080 
2081             // Numerically, sqrt(10^2N) = 10^N
2082             if (stripped.isPowerOfTen() &&
2083                 strippedScale % 2 == 0) {
2084                 BigDecimal result = valueOf(1L, strippedScale/2);
2085                 if (result.scale() != preferredScale) {
2086                     // Adjust to requested precision and preferred
2087                     // scale as appropriate.
2088                     result = result.add(zeroWithFinalPreferredScale, mc);
2089                 }
2090                 return result;
2091             }
2092 
2093             System.out.println("\tStarting: " + this + "\tscale: " + this.scale()); // DEBUG
2094             System.out.println("\tStripped: " + stripped + "\tscale: " + stripped.scale()); // DEBUG
2095 
2096 
2097             // After stripTrailingZeros, the representation is normalized as
2098             //
2099             // unscaledValue * 10^(-scale)
2100             //
2101             // where unscaledValue is an integer with the mimimum
2102             // precision for the cohort of the numerical value. To
2103             // allow binary floating-point hardware to be used to get
2104             // approximately a 15 digit approximation to the square
2105             // root, it is helpful to instead normalize this as so
2106             // that the significand portion is to right of the decimal
2107             // point, roughly:
2108             //
2109             // (unscaledValue * (10^-precision) * 10^(-scale)) * (10^precision)
2110             //
2111             // so that
2112             //
2113             // sqrt(unscaledValue * (10^-precision) * 10^(-scale) * (10^precision)) =
2114             //
2115             // sqrt(unscaledValue * (10^-precision) * 10^(-scale)) * 10^(precision/2)
2116             //
2117             // Therefore, this adjustment occurs for by 10^-precision is precision is even or 
2118             // (adjust as needed, +/-1
2119             //
2120 
2121             // Now the precision / scale adjustment
2122             int scaleAdjust = 0;
2123             int scale = stripped.scale() - stripped.precision() + 1;
2124             if (scale % 2 == 0) {
2125                 scaleAdjust = scale;
2126             } else {
2127                 scaleAdjust = scale - 1;
2128                 // stripped = stripped.multiply(TEN); why not??
2129             }
2130 
2131             // For extreme values, large exponents with huge
2132             // significands, this scale adjustment can overflow. (?)
2133             BigDecimal working = stripped.scaleByPowerOfTen(scaleAdjust);
2134             System.out.println("\tWorking2: " + working + "\tscale: " + working.scale() +
2135                                "\tadjust: " + scaleAdjust); // DEBUG
2136 
2137             assert  // Verify 0.1 <= working < 10
2138                 ONE_TENTH.compareTo(working) <= 0 &&
2139                 working.compareTo(TEN) < 0;
2140 
2141             // Use good ole' Math.sqrt to get the initial guess for
2142             // the Newton iteration, good to at least 15 decimal
2143             // digits. This approach does incur the cost of
2144             //
2145             // BigDecimal -> double -> BigDecimal
2146             // 
2147             // conversion cycle, but it avoids the need for several
2148             // Newton iterations in BigDecimal arithmetic to get the
2149             // working answer to 15 digits of precision. If many fewer
2150             // than 15 digits were needed, it might be faster to do
2151             // the loop entirely in BigDecimal arithmetic.
2152             //
2153             // (A double value might have as much many as 17 decimal
2154             // digits of precision; it depends on the relative density
2155             // of binary and decimal numbers at different regions of
2156             // the number line.)
2157             //
2158             // (It would be possible to check for certain special
2159             // cases to avoid doing any Newton iterations. For
2160             // example, if the BigDecimal -> double conversion were
2161             // known to be exact and the rounding mode had a
2162             // low-enough precision, the post-Newton rounding logic
2163             // could be applied directly.)
2164 
2165             BigDecimal guess = new BigDecimal(Math.sqrt(working.doubleValue()));
2166             int guessPrecision = 15;
2167             int originalPrecision = mc.getPrecision();
2168             int targetPrecision;
2169 
2170             // If an exact value is requested, it must only need about
2171             // half of the input digits to represent since multiplying
2172             // two N digit numbers yield a 2N-1 digit or 2N digit result.
2173             if (originalPrecision == 0) {
2174                 targetPrecision = stripped.precision()/2 + 1;
2175             } else {
2176                 targetPrecision = originalPrecision;
2177             }
2178 
2179             // When setting the precision to use inside the Newton
2180             // iteration loop, take care to avoid the case where the
2181             // precision of the input exceeds the requested precision
2182             // and rounding the input value too soon.
2183             BigDecimal approx = guess;
2184             int workingPrecision = working.precision();
2185             do {
2186                 // If did more work, could we make sure the
2187                 // approximation was uniformly above / below the root?
2188 
2189                 // System.out.println(approx); // DEBUG
2190                 int tmpPrecision = Math.max(Math.max(guessPrecision, targetPrecision + 2),
2191                                            workingPrecision);
2192                 MathContext mcTmp = new MathContext(tmpPrecision, RoundingMode.HALF_EVEN);
2193                 // approx = 0.5 * (approx + fraction / approx)
2194                 approx = ONE_HALF.multiply(approx.add(working.divide(approx, mcTmp), mcTmp));
2195                 guessPrecision *= 2;
2196             } while (guessPrecision < targetPrecision + 2);
2197 
2198             // Need additinal checking for HALF_EVEN since we are only
2199             // using two extra precision digits and don't have a sticky bit?
2200             BigDecimal result;
2201             RoundingMode targetRm = mc.getRoundingMode();
2202             if (targetRm == RoundingMode.UNNECESSARY || originalPrecision == 0) {
2203                 RoundingMode tmpRm =
2204                     (targetRm == RoundingMode.UNNECESSARY) ? RoundingMode.DOWN : targetRm;
2205                 MathContext mcTmp = new MathContext(targetPrecision, tmpRm);
2206                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mcTmp);
2207 
2208                 // If result*result != this numerically, the square
2209                 // root isn't exact
2210                 if (this.subtract(result.multiply(result)).compareTo(ZERO) != 0) {
2211                     throw new ArithmeticException("Computed square root not exact.");
2212                 }
2213             } else {
2214                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mc);
2215             }
2216 
2217             if (result.scale() != preferredScale) {
2218                 // The preferred scale of an add is
2219                 // max(addend.scale(), augend.scale()). Therefore, if
2220                 // the scale of the result is first minimized using
2221                 // stripTrailingZeros(), adding a zero of the
2222                 // preferred scale rounding the correct precision will
2223                 // perform the proper scale vs precision tradeoffs.
2224                 result = result.stripTrailingZeros().
2225                     add(zeroWithFinalPreferredScale,
2226                         new MathContext(originalPrecision, RoundingMode.UNNECESSARY));
2227             }
2228             assert squareRootResultAssertions(result, mc);
2229             return result;
2230         } else {
2231             switch (signum) {
2232             case -1:
2233                 throw new ArithmeticException("Attempted square root " + 
2234                                               "of negative BigDecimal");
2235             case 0:
2236                 return valueOf(0L, scale()/2);
2237 
2238             default:
2239                 throw new AssertionError("Bad value from signum");
2240             }
2241         }
2242     }
2243 
2244     private boolean isPowerOfTen() {
2245         return BigInteger.ONE.equals(this.unscaledValue());
2246     }
2247 
2248     /**
2249      * For nonzero values, check numerical correctness properties of
2250      * the computed result for the chosen rounding mode .
2251      *
2252      * For the directed roundings, for DOWN and FLOOR, result^2 must
2253      * be {@code <=} the input and (result+ulp)^2 must be {@code >} the
2254      * input. Conversely, for UP and CEIL, result^2 must be {@code >=} the
2255      * input and (result-ulp)^2 must be {@code <} the input.
2256      */
2257     private boolean squareRootResultAssertions(BigDecimal result, MathContext mc) {
2258         if (result.signum() == 0) {
2259             return squareRootZeroResultAssertions(result, mc);
2260         } else {
2261             RoundingMode rm = mc.getRoundingMode();
2262             BigDecimal ulp = result.ulp();
2263             BigDecimal neighborUp   = result.add(ulp);
2264             // Make neighbor down accruate even for powers of ten
2265             if (this.isPowerOfTen()) {
2266                 ulp = ulp.divide(TEN);
2267             }
2268             BigDecimal neighborDown = result.subtract(ulp);
2269 
2270             switch (rm) {
2271             case DOWN: 
2272             case FLOOR:
2273                 return
2274                     result.multiply(result).compareTo(this)         <= 0 &&
2275                     neighborUp.multiply(neighborUp).compareTo(this) > 0;
2276 
2277             case UP: 
2278             case CEILING:
2279                 return
2280                     result.multiply(result).compareTo(this)             >= 0 &&
2281                     neighborDown.multiply(neighborDown).compareTo(this) < 0;
2282 
2283             case HALF_DOWN:
2284             case HALF_EVEN:
2285             case HALF_UP:
2286                 BigDecimal err = result.multiply(result).subtract(this).abs();
2287                 BigDecimal errUp = neighborUp.multiply(neighborUp).subtract(this); 
2288                 BigDecimal errDown =  this.subtract(neighborDown.multiply(neighborDown));
2289                 // All error values should be positive so don't need to
2290                 // compare absolute values.
2291 
2292                 int err_comp_errUp = err.compareTo(errUp);
2293                 int err_comp_errDown = err.compareTo(errDown);
2294 
2295                 return
2296                     errUp.signum()   == 1 &&
2297                     errDown.signum() == 1 && 
2298 
2299                     err_comp_errUp   <= 0 &&
2300                     err_comp_errDown <= 0 &&
2301 
2302                     ((err_comp_errUp   == 0 ) ? err_comp_errDown < 0 : true) &&
2303                     ((err_comp_errDown == 0 ) ? err_comp_errUp   < 0 : true);
2304                 // && could check for digit conditions for ties too
2305 
2306             default: // Definition of UNNECESSARY already verified.
2307                 return true;
2308             }
2309         }
2310     }
2311 
2312     private boolean squareRootZeroResultAssertions(BigDecimal result, MathContext mc) {
2313         return true; // TBD
2314     }
2315 
2316     /**
2317      * Returns a {@code BigDecimal} whose value is
2318      * <code>(this<sup>n</sup>)</code>, The power is computed exactly, to
2319      * unlimited precision.
2320      *
2321      * <p>The parameter {@code n} must be in the range 0 through
2322      * 999999999, inclusive.  {@code ZERO.pow(0)} returns {@link
2323      * #ONE}.
2324      *
2325      * Note that future releases may expand the allowable exponent
2326      * range of this method.
2327      *
2328      * @param  n power to raise this {@code BigDecimal} to.
2329      * @return <code>this<sup>n</sup></code>
2330      * @throws ArithmeticException if {@code n} is out of range.
2331      * @since  1.5
2332      */
2333     public BigDecimal pow(int n) {


< prev index next >