< prev index next >

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

Print this page




2187                 // approx = 0.5 * (approx + fraction / approx)
2188                 approx = ONE_HALF.multiply(approx.add(working.divide(approx, mcTmp), mcTmp));
2189                 guessPrecision *= 2;
2190             } while (guessPrecision < targetPrecision + 2);
2191 
2192             BigDecimal result;
2193             RoundingMode targetRm = mc.getRoundingMode();
2194             if (targetRm == RoundingMode.UNNECESSARY || originalPrecision == 0) {
2195                 RoundingMode tmpRm =
2196                     (targetRm == RoundingMode.UNNECESSARY) ? RoundingMode.DOWN : targetRm;
2197                 MathContext mcTmp = new MathContext(targetPrecision, tmpRm);
2198                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mcTmp);
2199 
2200                 // If result*result != this numerically, the square
2201                 // root isn't exact
2202                 if (this.subtract(result.multiply(result)).compareTo(ZERO) != 0) {
2203                     throw new ArithmeticException("Computed square root not exact.");
2204                 }
2205             } else {
2206                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mc);

































2207             }
2208 
2209             if (result.scale() != preferredScale) {
2210                 // The preferred scale of an add is
2211                 // max(addend.scale(), augend.scale()). Therefore, if
2212                 // the scale of the result is first minimized using
2213                 // stripTrailingZeros(), adding a zero of the
2214                 // preferred scale rounding the correct precision will
2215                 // perform the proper scale vs precision tradeoffs.
2216                 result = result.stripTrailingZeros().
2217                     add(zeroWithFinalPreferredScale,
2218                         new MathContext(originalPrecision, RoundingMode.UNNECESSARY));
2219             }
2220             assert squareRootResultAssertions(result, mc);
2221             return result;
2222         } else {
2223             switch (signum) {
2224             case -1:
2225                 throw new ArithmeticException("Attempted square root " +
2226                                               "of negative BigDecimal");




2187                 // approx = 0.5 * (approx + fraction / approx)
2188                 approx = ONE_HALF.multiply(approx.add(working.divide(approx, mcTmp), mcTmp));
2189                 guessPrecision *= 2;
2190             } while (guessPrecision < targetPrecision + 2);
2191 
2192             BigDecimal result;
2193             RoundingMode targetRm = mc.getRoundingMode();
2194             if (targetRm == RoundingMode.UNNECESSARY || originalPrecision == 0) {
2195                 RoundingMode tmpRm =
2196                     (targetRm == RoundingMode.UNNECESSARY) ? RoundingMode.DOWN : targetRm;
2197                 MathContext mcTmp = new MathContext(targetPrecision, tmpRm);
2198                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mcTmp);
2199 
2200                 // If result*result != this numerically, the square
2201                 // root isn't exact
2202                 if (this.subtract(result.multiply(result)).compareTo(ZERO) != 0) {
2203                     throw new ArithmeticException("Computed square root not exact.");
2204                 }
2205             } else {
2206                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mc);
2207                 
2208                 switch (targetRm) {
2209                 case DOWN:
2210                 case FLOOR:
2211                     // Check if too big
2212                     if (result.multiply(result).compareTo(this) > 0  ) {
2213                         BigDecimal ulp = ulp = result.ulp();
2214                         // Adjust increment down in case of 1.0 = 10^0
2215                         // since the next smaller number is 1/10
2216                         // closer than the next larger at exponent
2217                         // boundaries.
2218                         if (result.compareTo(ONE) == 0) {
2219                             ulp = ulp.multiply(ONE_TENTH);
2220                         }
2221                         result = result.subtract(ulp);
2222                     }
2223                     break;
2224 
2225                 case UP:
2226                 case CEILING:
2227                     // Check if too small
2228                     if (result.multiply(result).compareTo(this) < 0  ) {
2229                         result = result.add(result.ulp());
2230                     }
2231                     break;
2232 
2233                 default:
2234                     // Do nothing for half-way cases
2235                     // HALF_DOWN, HALF_EVEN, HALF_UP
2236                     // See fix-up in paper, up down by *1/2* ulp
2237                     break;
2238                 }
2239 
2240             }
2241 
2242             if (result.scale() != preferredScale) {
2243                 // The preferred scale of an add is
2244                 // max(addend.scale(), augend.scale()). Therefore, if
2245                 // the scale of the result is first minimized using
2246                 // stripTrailingZeros(), adding a zero of the
2247                 // preferred scale rounding the correct precision will
2248                 // perform the proper scale vs precision tradeoffs.
2249                 result = result.stripTrailingZeros().
2250                     add(zeroWithFinalPreferredScale,
2251                         new MathContext(originalPrecision, RoundingMode.UNNECESSARY));
2252             }
2253             assert squareRootResultAssertions(result, mc);
2254             return result;
2255         } else {
2256             switch (signum) {
2257             case -1:
2258                 throw new ArithmeticException("Attempted square root " +
2259                                               "of negative BigDecimal");


< prev index next >