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) { |