Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8273090

Add Math.ceilDiv() family parallel to Math.floorDiv() family

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P4
    • Resolution: Approved
    • Fix Version/s: 18
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Kind:
      behavioral
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      Additional methods to final classes.
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      Add methods ceilDiv(), ceilMod() and ceilDivExact(), paralleling the corresponding floorDiv(), floorMod() and floorDivExact methods, to java.lang.Math and java.lang.StrictMath.

      Problem

      The methods floorDiv() and floorMod() compute the integer quotient of their arguments and the corresponding remainder. They do so by applying floor rounding (rounding toward negative infinity) to the exact algebraic quotient. The are no methods to apply ceiling rounding instead (rounding toward positive infinity).

      As an example, when determining how many blocks of size n are minimally needed to host m items, the computation behind the scenes is something akin to ceilDiv(m, n). There are presumably many customized ceilDiv()-like computations in the code base, probably some of them incorrect at the extrema of the int/long ranges. An officially endorsed ceilDiv() family helps in minimizing errors in custom-made, ad-hoc solutions.

      Solution

      Add methods ceilDiv(), ceilMod() and ceilDivExact().

      Specification

          --- a/src/java.base/share/classes/java/lang/Math.java
          +++ b/src/java.base/share/classes/java/lang/Math.java
          @@ -1088,13 +1088,13 @@ public final class Math {
          +    /**
          +     * Returns the smallest (closest to negative infinity)
          +     * {@code int} value that is greater than or equal to the algebraic quotient.
          +     * This method is identical to {@link #ceilDiv(int,int)} except that it
          +     * throws an {@code ArithmeticException} when the dividend is
          +     * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is
          +     * {@code -1} instead of ignoring the integer overflow and returning
          +     * {@code Integer.MIN_VALUE}.
          +     * <p>
          +     * The ceil modulus method {@link #ceilMod(int,int)} is a suitable
          +     * counterpart both for this method and for the {@link #ceilDiv(int,int)}
          +     * method.
          +     * <p>
          +     * For examples, see {@link #ceilDiv(int, int)}.
          +     *
          +     * @param x the dividend
          +     * @param y the divisor
          +     * @return the smallest (closest to negative infinity)
          +     * {@code int} value that is greater than or equal to the algebraic quotient.
          +     * @throws ArithmeticException if the divisor {@code y} is zero, or the
          +     * dividend {@code x} is {@code Integer.MIN_VALUE} and the divisor {@code y}
          +     * is {@code -1}.
          +     * @see #ceilDiv(int, int)
          +     * @since 18
          +     */
          +    public static int ceilDivExact(int x, int y) {
          +
          +    /**
          +     * Returns the smallest (closest to negative infinity)
          +     * {@code long} value that is greater than or equal to the algebraic quotient.
          +     * This method is identical to {@link #ceilDiv(long,long)} except that it
          +     * throws an {@code ArithmeticException} when the dividend is
          +     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is
          +     * {@code -1} instead of ignoring the integer overflow and returning
          +     * {@code Long.MIN_VALUE}.
          +     * <p>
          +     * The ceil modulus method {@link #ceilMod(long,long)} is a suitable
          +     * counterpart both for this method and for the {@link #ceilDiv(long,long)}
          +     * method.
          +     * <p>
          +     * For examples, see {@link #ceilDiv(int, int)}.
          +     *
          +     * @param x the dividend
          +     * @param y the divisor
          +     * @return the smallest (closest to negative infinity)
          +     * {@code long} value that is greater than or equal to the algebraic quotient.
          +     * @throws ArithmeticException if the divisor {@code y} is zero, or the
          +     * dividend {@code x} is {@code Long.MIN_VALUE} and the divisor {@code y}
          +     * is {@code -1}.
          +     * @see #ceilDiv(long,long)
          +     * @since 18
          +     */
          +    public static long ceilDivExact(long x, long y) {
      
          @@ -1361,12 +1435,12 @@ public final class Math {
          @@ -1530,12 +1604,226 @@ public final class Math {
          +    /**
          +     * Returns the smallest (closest to negative infinity)
          +     * {@code int} value that is greater than or equal to the algebraic quotient.
          +     * There is one special case: if the dividend is
          +     * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1},
          +     * then integer overflow occurs and
          +     * the result is equal to {@code Integer.MIN_VALUE}.
          +     * <p>
          +     * Normal integer division operates under the round to zero rounding mode
          +     * (truncation).  This operation instead acts under the round toward
          +     * positive infinity (ceiling) rounding mode.
          +     * The ceiling rounding mode gives different results from truncation
          +     * when the exact quotient is not an integer and is positive.
          +     * <ul>
          +     *   <li>If the signs of the arguments are different, the results of
          +     *       {@code ceilDiv} and the {@code /} operator are the same.  <br>
          +     *       For example, {@code ceilDiv(-4, 3) == -1} and {@code (-4 / 3) == -1}.</li>
          +     *   <li>If the signs of the arguments are the same, {@code ceilDiv}
          +     *       returns the smallest integer greater than or equal to the quotient
          +     *       while the {@code /} operator returns the largest integer less
          +     *       than or equal to the quotient.
          +     *       They differ if and only if the quotient is not an integer.<br>
          +     *       For example, {@code ceilDiv(4, 3) == 2},
          +     *       whereas {@code (4 / 3) == 1}.
          +     *   </li>
          +     * </ul>
          +     *
          +     * @param x the dividend
          +     * @param y the divisor
          +     * @return the smallest (closest to negative infinity)
          +     * {@code int} value that is greater than or equal to the algebraic quotient.
          +     * @throws ArithmeticException if the divisor {@code y} is zero
          +     * @see #ceilMod(int, int)
          +     * @see #ceil(double)
          +     * @since 18
          +     */
          +    public static int ceilDiv(int x, int y) {
          +
          +    /**
          +     * Returns the smallest (closest to negative infinity)
          +     * {@code long} value that is greater than or equal to the algebraic quotient.
          +     * There is one special case: if the dividend is
          +     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
          +     * then integer overflow occurs and
          +     * the result is equal to {@code Long.MIN_VALUE}.
          +     * <p>
          +     * Normal integer division operates under the round to zero rounding mode
          +     * (truncation).  This operation instead acts under the round toward
          +     * positive infinity (ceiling) rounding mode.
          +     * The ceiling rounding mode gives different results from truncation
          +     * when the exact result is not an integer and is positive.
          +     * <p>
          +     * For examples, see {@link #ceilDiv(int, int)}.
          +     *
          +     * @param x the dividend
          +     * @param y the divisor
          +     * @return the smallest (closest to negative infinity)
          +     * {@code long} value that is greater than or equal to the algebraic quotient.
          +     * @throws ArithmeticException if the divisor {@code y} is zero
          +     * @see #ceilMod(int, int)
          +     * @see #ceil(double)
          +     * @since 18
          +     */
          +    public static long ceilDiv(long x, int y) {
          +
          +    /**
          +     * Returns the smallest (closest to negative infinity)
          +     * {@code long} value that is greater than or equal to the algebraic quotient.
          +     * There is one special case: if the dividend is
          +     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
          +     * then integer overflow occurs and
          +     * the result is equal to {@code Long.MIN_VALUE}.
          +     * <p>
          +     * Normal integer division operates under the round to zero rounding mode
          +     * (truncation).  This operation instead acts under the round toward
          +     * positive infinity (ceiling) rounding mode.
          +     * The ceiling rounding mode gives different results from truncation
          +     * when the exact result is not an integer and is positive.
          +     * <p>
          +     * For examples, see {@link #ceilDiv(int, int)}.
          +     *
          +     * @param x the dividend
          +     * @param y the divisor
          +     * @return the smallest (closest to negative infinity)
          +     * {@code long} value that is greater than or equal to the algebraic quotient.
          +     * @throws ArithmeticException if the divisor {@code y} is zero
          +     * @see #ceilMod(int, int)
          +     * @see #ceil(double)
          +     * @since 18
          +     */
          +    public static long ceilDiv(long x, long y) {
          +
          +    /**
          +     * Returns the ceiling modulus of the {@code int} arguments.
          +     * <p>
          +     * The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
          +     * has the opposite sign as the divisor {@code y} or is zero, and
          +     * is in the range of {@code -abs(y) < r < +abs(y)}.
          +     *
          +     * <p>
          +     * The relationship between {@code ceilDiv} and {@code ceilMod} is such that:
          +     * <ul>
          +     *   <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
          +     * </ul>
          +     * <p>
          +     * The difference in values between {@code ceilMod} and the {@code %} operator
          +     * is due to the difference between {@code ceilDiv} and the {@code /}
          +     * operator, as detailed in {@linkplain #ceilDiv(int, int)}.
          +     * <p>
          +     * Examples:
          +     * <ul>
          +     *   <li>Regardless of the signs of the arguments, {@code ceilMod}(x, y)
          +     *       is zero exactly when {@code x % y} is zero as well.</li>
          +     *   <li>If neither {@code ceilMod}(x, y) nor {@code x % y} is zero,
          +     *       they differ exactly when the signs of the arguments are the same.<br>
          +     *       <ul>
          +     *       <li>{@code ceilMod(+4, +3) == -2}; &nbsp; and {@code (+4 % +3) == +1}</li>
          +     *       <li>{@code ceilMod(-4, -3) == +2}; &nbsp; and {@code (-4 % -3) == -1}</li>
          +     *       <li>{@code ceilMod(+4, -3) == +1}; &nbsp; and {@code (+4 % -3) == +1}</li>
          +     *       <li>{@code ceilMod(-4, +3) == -1}; &nbsp; and {@code (-4 % +3) == -1}</li>
          +     *       </ul>
          +     *   </li>
          +     * </ul>
          +     *
          +     * @param x the dividend
          +     * @param y the divisor
          +     * @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
          +     * @throws ArithmeticException if the divisor {@code y} is zero
          +     * @see #ceilDiv(int, int)
          +     * @since 18
          +     */
          +    public static int ceilMod(int x, int y) {
          +
          +    /**
          +     * Returns the ceiling modulus of the {@code long} and {@code int} arguments.
          +     * <p>
          +     * The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
          +     * has the opposite sign as the divisor {@code y} or is zero, and
          +     * is in the range of {@code -abs(y) < r < +abs(y)}.
          +     *
          +     * <p>
          +     * The relationship between {@code ceilDiv} and {@code ceilMod} is such that:
          +     * <ul>
          +     *   <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
          +     * </ul>
          +     * <p>
          +     * For examples, see {@link #ceilMod(int, int)}.
          +     *
          +     * @param x the dividend
          +     * @param y the divisor
          +     * @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
          +     * @throws ArithmeticException if the divisor {@code y} is zero
          +     * @see #ceilDiv(long, int)
          +     * @since 18
          +     */
          +    public static int ceilMod(long x, int y) {
          +
          +    /**
          +     * Returns the ceiling modulus of the {@code long} arguments.
          +     * <p>
          +     * The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
          +     * has the opposite sign as the divisor {@code y} or is zero, and
          +     * is in the range of {@code -abs(y) < r < +abs(y)}.
          +     *
          +     * <p>
          +     * The relationship between {@code ceilDiv} and {@code ceilMod} is such that:
          +     * <ul>
          +     *   <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
          +     * </ul>
          +     * <p>
          +     * For examples, see {@link #ceilMod(int, int)}.
          +     *
          +     * @param x the dividend
          +     * @param y the divisor
          +     * @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
          +     * @throws ArithmeticException if the divisor {@code y} is zero
          +     * @see #ceilDiv(long, long)
          +     * @since 18
          +     */
          +    public static long ceilMod(long x, long y) {
      
      --- a/src/java.base/share/classes/java/lang/StrictMath.java
      +++ b/src/java.base/share/classes/java/lang/StrictMath.java
      @@ -967,6 +967,66 @@ public final class StrictMath {
      +    /**
      +     * Returns the smallest (closest to negative infinity)
      +     * {@code int} value that is greater than or equal to the algebraic quotient.
      +     * This method is identical to {@link #ceilDiv(int,int)} except that it
      +     * throws an {@code ArithmeticException} when the dividend is
      +     * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is
      +     * {@code -1} instead of ignoring the integer overflow and returning
      +     * {@code Integer.MIN_VALUE}.
      +     * <p>
      +     * The ceil modulus method {@link #ceilMod(int,int)} is a suitable
      +     * counterpart both for this method and for the {@link #ceilDiv(int,int)}
      +     * method.
      +     * <p>
      +     * See {@link Math#ceilDiv(int, int) Math.ceilDiv} for examples and
      +     * a comparison to the integer division {@code /} operator.
      +     *
      +     * @param x the dividend
      +     * @param y the divisor
      +     * @return the smallest (closest to negative infinity)
      +     * {@code int} value that is greater than or equal to the algebraic quotient.
      +     * @throws ArithmeticException if the divisor {@code y} is zero, or the
      +     * dividend {@code x} is {@code Integer.MIN_VALUE} and the divisor {@code y}
      +     * is {@code -1}.
      +     * @see Math#ceilDiv(int, int)
      +     * @since 18
      +     */
      +    public static int ceilDivExact(int x, int y) {
      +
      +    /**
      +     * Returns the smallest (closest to negative infinity)
      +     * {@code long} value that is greater than or equal to the algebraic quotient.
      +     * This method is identical to {@link #ceilDiv(long,long)} except that it
      +     * throws an {@code ArithmeticException} when the dividend is
      +     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is
      +     * {@code -1} instead of ignoring the integer overflow and returning
      +     * {@code Long.MIN_VALUE}.
      +     * <p>
      +     * The ceil modulus method {@link #ceilMod(long,long)} is a suitable
      +     * counterpart both for this method and for the {@link #ceilDiv(long,long)}
      +     * method.
      +     * <p>
      +     * For examples, see {@link Math#ceilDiv(int, int) Math.ceilDiv}.
      +     *
      +     * @param x the dividend
      +     * @param y the divisor
      +     * @return the smallest (closest to negative infinity)
      +     * {@code long} value that is greater than or equal to the algebraic quotient.
      +     * @throws ArithmeticException if the divisor {@code y} is zero, or the
      +     * dividend {@code x} is {@code Long.MIN_VALUE} and the divisor {@code y}
      +     * is {@code -1}.
      +     * @see Math#ceilDiv(int, int)
      +     * @see Math#ceilDiv(long,long)
      +     * @since 18
      +     */
      +    public static long ceilDivExact(long x, long y) {
      +
      +    /**
      +     * Returns the smallest (closest to negative infinity)
      +     * {@code int} value that is greater than or equal to the algebraic quotient.
      +     * There is one special case: if the dividend is
      +     * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1},
      +     * then integer overflow occurs and
      +     * the result is equal to {@code Integer.MIN_VALUE}.
      +     * <p>
      +     * See {@link Math#ceilDiv(int, int) Math.ceilDiv} for examples and
      +     * a comparison to the integer division {@code /} operator.
      +     *
      +     * @param x the dividend
      +     * @param y the divisor
      +     * @return the smallest (closest to negative infinity)
      +     * {@code int} value that is greater than or equal to the algebraic quotient.
      +     * @throws ArithmeticException if the divisor {@code y} is zero
      +     * @see Math#ceilDiv(int, int)
      +     * @see Math#ceil(double)
      +     * @since 18
      +     */
      +    public static int ceilDiv(int x, int y) {
      +
      +    /**
      +     * Returns the smallest (closest to negative infinity)
      +     * {@code long} value that is greater than or equal to the algebraic quotient.
      +     * There is one special case: if the dividend is
      +     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
      +     * then integer overflow occurs and
      +     * the result is equal to {@code Long.MIN_VALUE}.
      +     * <p>
      +     * See {@link Math#ceilDiv(int, int) Math.ceilDiv} for examples and
      +     * a comparison to the integer division {@code /} operator.
      +     *
      +     * @param x the dividend
      +     * @param y the divisor
      +     * @return the smallest (closest to negative infinity)
      +     * {@code long} value that is greater than or equal to the algebraic quotient.
      +     * @throws ArithmeticException if the divisor {@code y} is zero
      +     * @see Math#ceilDiv(long, int)
      +     * @see Math#ceil(double)
      +     * @since 18
      +     */
      +    public static long ceilDiv(long x, int y) {
      +
      +    /**
      +     * Returns the smallest (closest to negative infinity)
      +     * {@code long} value that is greater than or equal to the algebraic quotient.
      +     * There is one special case: if the dividend is
      +     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
      +     * then integer overflow occurs and
      +     * the result is equal to {@code Long.MIN_VALUE}.
      +     * <p>
      +     * See {@link Math#ceilDiv(int, int) Math.ceilDiv} for examples and
      +     * a comparison to the integer division {@code /} operator.
      +     *
      +     * @param x the dividend
      +     * @param y the divisor
      +     * @return the smallest (closest to negative infinity)
      +     * {@code long} value that is greater than or equal to the algebraic quotient.
      +     * @throws ArithmeticException if the divisor {@code y} is zero
      +     * @see Math#ceilDiv(long, long)
      +     * @see Math#ceil(double)
      +     * @since 18
      +     */
      +    public static long ceilDiv(long x, long y) {
      +
      +    /**
      +     * Returns the ceiling modulus of the {@code int} arguments.
      +     * <p>
      +     * The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
      +     * has the opposite sign as the divisor {@code y} or is zero, and
      +     * is in the range of {@code -abs(y) < r < +abs(y)}.
      +     *
      +     * <p>
      +     * The relationship between {@code ceilDiv} and {@code ceilMod} is such that:
      +     * <ul>
      +     *   <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
      +     * </ul>
      +     * <p>
      +     * See {@link Math#ceilMod(int, int) Math.ceilMod} for examples and
      +     * a comparison to the {@code %} operator.
      +     *
      +     * @param x the dividend
      +     * @param y the divisor
      +     * @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
      +     * @throws ArithmeticException if the divisor {@code y} is zero
      +     * @see Math#ceilMod(int, int)
      +     * @see StrictMath#ceilDiv(int, int)
      +     * @since 18
      +     */
      +    public static int ceilMod(int x, int y) {
      +
      +    /**
      +     * Returns the ceiling modulus of the {@code long} and {@code int} arguments.
      +     * <p>
      +     * The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
      +     * has the opposite sign as the divisor {@code y} or is zero, and
      +     * is in the range of {@code -abs(y) < r < +abs(y)}.
      +     *
      +     * <p>
      +     * The relationship between {@code ceilDiv} and {@code ceilMod} is such that:
      +     * <ul>
      +     *   <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
      +     * </ul>
      +     * <p>
      +     * See {@link Math#ceilMod(int, int) Math.ceilMod} for examples and
      +     * a comparison to the {@code %} operator.
      +     *
      +     * @param x the dividend
      +     * @param y the divisor
      +     * @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
      +     * @throws ArithmeticException if the divisor {@code y} is zero
      +     * @see Math#ceilMod(long, int)
      +     * @see StrictMath#ceilDiv(long, int)
      +     * @since 18
      +     */
      +    public static int ceilMod(long x, int y) {
      +
      +    /**
      +     * Returns the ceiling modulus of the {@code long} arguments.
      +     * <p>
      +     * The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
      +     * has the opposite sign as the divisor {@code y} or is zero, and
      +     * is in the range of {@code -abs(y) < r < +abs(y)}.
      +     *
      +     * <p>
      +     * The relationship between {@code ceilDiv} and {@code ceilMod} is such that:
      +     * <ul>
      +     *   <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
      +     * </ul>
      +     * <p>
      +     * See {@link Math#ceilMod(int, int) Math.ceilMod} for examples and
      +     * a comparison to the {@code %} operator.
      +     *
      +     * @param x the dividend
      +     * @param y the divisor
      +     * @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
      +     * @throws ArithmeticException if the divisor {@code y} is zero
      +     * @see Math#ceilMod(long, long)
      +     * @see StrictMath#ceilDiv(long, long)
      +     * @since 18
      +     */
      +    public static long ceilMod(long x, long y) {

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              rgiulietti Raffaello Giulietti
              Reporter:
              webbuggrp Webbug Group
              Reviewed By:
              Brian Burkhalter
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: