JDK-8366479 : BigDecimal roots
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.math
  • Priority: P4
  • Status: Finalized
  • Resolution: Unresolved
  • Fix Versions: 26
  • Submitted: 2025-08-30
  • Updated: 2025-10-27
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Add `rootn()` method in class `BigDecimal`.

Problem
-------
The class `BigDecimal` already provides methods `pow()` and `sqrt()` for power and square root calculation, so, for symmetry, it would be useful introducing a method to compute integer nth roots too.
 
Solution
--------

Implement `rootn()` method in class `BigDecimal`.

Specification
-------------

    /**
     * Returns an approximation to the {@code n}<sup>th</sup> root of {@code this}
     * with rounding according to the context settings.
     *
     * <p>The preferred scale of the returned result is equal to
     * {@code Math.ceilDiv(this.scale(), n)}. The value of the returned result is
     * always within one ulp of the exact decimal value for the
     * precision in question.  If the rounding mode is {@link
     * RoundingMode#HALF_UP HALF_UP}, {@link RoundingMode#HALF_DOWN
     * HALF_DOWN}, or {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
     * result is within one half an ulp of the exact decimal value.
     *
     * <p>Special case:
     * <ul>
     * <li> The {@code n}<sup>th</sup> root of a number numerically equal to {@code
     * ZERO} is numerically equal to {@code ZERO} with a preferred
     * scale according to the general rule above. In particular, for
     * {@code ZERO}, {@code ZERO.rootn(n, mc).equals(ZERO)} is true with
     * any {@code MathContext} as an argument.
     * </ul>
     *
     * @param n the root degree
     * @param mc the context to use.
     * @return the {@code n}<sup>th</sup> root of {@code this}.
     * @throws ArithmeticException if {@code n == 0 || n == Integer.MIN_VALUE}.
     * @throws ArithmeticException if {@code n} is even and {@code this} is negative.
     * @throws ArithmeticException if {@code n} is negative and {@code this} is zero.
     * @throws ArithmeticException if an exact result is requested
     * ({@code mc.getPrecision() == 0}) and there is no finite decimal
     * expansion of the exact result
     * @throws ArithmeticException if
     * {@code (mc.getRoundingMode() == RoundingMode.UNNECESSARY}) and
     * the exact result cannot fit in {@code mc.getPrecision()} digits.
     * @see #sqrt(MathContext)
     * @see BigInteger#rootn(int)
     * @since 26
     * @apiNote Note that calling {@code rootn(2, mc)} is equivalent to calling {@code sqrt(mc)}.
     */
    public BigDecimal rootn(int n, MathContext mc)


Comments
Moving to Finalized.
27-10-2025

[~fromano] I renamed BigInteger.nthRoot to BigInteger.rootn in the 2nd `@see`. There's a whole paragraph for ZERO, but does it deserve to be called a special case?
27-10-2025

[~rgiulietti]; please review this CSR; moving to Provisional under that review is done.
27-10-2025

FYI, as a point of reference, here is the IEEE 754-2019 special cases for rootn: > For the rootn operation: > > - rootn (±0, n) is ±∞ and signals the divideByZero exception for odd n < 0 > - rootn (±0, n) is +∞ and signals the divideByZero exception for even n < 0 > - rootn (±0, n) is +0 for even n > 0 > - rootn (±0, n) is ±0 for odd n > 0 > - rootn (+∞, n) is +∞ for n > 0 > - rootn (−∞, n) is −∞ for odd n > 0 > - rootn (−∞, n) is qNaN and signals the invalid operation exception for even n > 0 > - rootn (+∞, n) is +0 for n < 0 > - rootn (−∞, n) is −0 for odd n < 0 > - rootn (−∞, n) is qNaN and signals the invalid operation exception for even n < 0. > > NOTE — rootn (−0, 2) differs from squareRoot(−0) because they have > different consistency considerations. `BigDecimal` doesn't have negative zero or infinity values, of course.
08-09-2025

[~fromano], acknowledged.
05-09-2025

[~darcy] I think it would be better to look at the implementation, in order to understand better this specification.
03-09-2025

Moving to Provisional, not Approved. Hmm. I haven't look at the implementation at all (or thought about how this might be implemented). With those caveats, it would be preferable if not strictly required for the error bounds to be smaller. If a rounding mode of unnecessary is implemented in the expected way -- any inexactness in the result throws an exception -- then presumably correctly rounding (less than 0.5 ulps) could be implemented at some (perhaps high) cost. (The specification of the BigDecimal.pow method is atypical for the class should I don't think should be viewed as a precedent to emulate.)
03-09-2025