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

Javadoc of floorDiv() and floorMod() families is inaccurate in some places

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 18
    • core-libs
    • None
    • behavioral
    • minimal
    • Specification clarification and correction to better match actual behavior so there is no risk.
    • Java API
    • SE

      Summary

      Improve specifications of Math.floorDiv() and Math.floorMod() and their StrictMath siblings.

      Problem

      Some of the specification verbiage is unclear or simply incorrect. For example there is the statement in the floorDiv() specification

      the / operator returns the integer closest to zero

      when the integer closest to zero is zero itself.

      Solution

      Revise the verbiage to be clear and correct.

      Specification

      --- a/src/java.base/share/classes/java/lang/Math.java
      +++ b/src/java.base/share/classes/java/lang/Math.java
      @@ -1247,7 +1247,7 @@
           /**
            * Returns the largest (closest to positive infinity)
            * {@code int} value that is less than or equal to the algebraic quotient.
      -     * There is one special case, if the dividend is the
      +     * 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}.
      @@ -1256,7 +1256,7 @@
            * (truncation).  This operation instead acts under the round toward
            * negative infinity (floor) rounding mode.
            * The floor rounding mode gives different results from truncation
      -     * when the exact result is negative.
      +     * when the exact quotient is not an integer and is negative.
            * <ul>
            *   <li>If the signs of the arguments are the same, the results of
            *       {@code floorDiv} and the {@code /} operator are the same.  <br>
      @@ -1261,9 +1261,11 @@
            *   <li>If the signs of the arguments are the same, the results of
            *       {@code floorDiv} and the {@code /} operator are the same.  <br>
            *       For example, {@code floorDiv(4, 3) == 1} and {@code (4 / 3) == 1}.</li>
      -     *   <li>If the signs of the arguments are different,  the quotient is negative and
      -     *       {@code floorDiv} returns the integer less than or equal to the quotient
      -     *       and the {@code /} operator returns the integer closest to zero.<br>
      +     *   <li>If the signs of the arguments are different, {@code floorDiv}
      +     *       returns the largest integer less than or equal to the quotient
      +     *       while the {@code /} operator returns the smallest integer greater
      +     *       than or equal to the quotient.
      +     *       They differ if and only if the quotient is not an integer.<br>
            *       For example, {@code floorDiv(-4, 3) == -2},
            *       whereas {@code (-4 / 3) == -1}.
            *   </li>
      @@ -1290,7 +1292,7 @@
           /**
            * Returns the largest (closest to positive infinity)
            * {@code long} value that is less than or equal to the algebraic quotient.
      -     * There is one special case, if the dividend is the
      +     * 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}.
      @@ -1299,7 +1301,7 @@
            * (truncation).  This operation instead acts under the round toward
            * negative infinity (floor) rounding mode.
            * The floor rounding mode gives different results from truncation
      -     * when the exact result is negative.
      +     * when the exact result is not an integer and is negative.
            * <p>
            * For examples, see {@link #floorDiv(int, int)}.
            *
      @@ -1319,7 +1321,7 @@
           /**
            * Returns the largest (closest to positive infinity)
            * {@code long} value that is less than or equal to the algebraic quotient.
      -     * There is one special case, if the dividend is the
      +     * 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}.
      @@ -1328,7 +1330,7 @@
            * (truncation).  This operation instead acts under the round toward
            * negative infinity (floor) rounding mode.
            * The floor rounding mode gives different results from truncation
      -     * when the exact result is negative.
      +     * when the exact result is not an integer and is negative.
            * <p>
            * For examples, see {@link #floorDiv(int, int)}.
            *
      @@ -1353,8 +1355,8 @@
           /**
            * Returns the floor modulus of the {@code int} arguments.
            * <p>
      -     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
      -     * has the same sign as the divisor {@code y}, and
      +     * The floor modulus is {@code r = x - (floorDiv(x, y) * y)},
      +     * has the same sign as the divisor {@code y} or is zero, and
            * is in the range of {@code -abs(y) < r < +abs(y)}.
            *
            * <p>
      @@ -1360,25 +1362,22 @@
            * <p>
            * The relationship between {@code floorDiv} and {@code floorMod} is such that:
            * <ul>
      -     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
      +     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}</li>
            * </ul>
            * <p>
      -     * The difference in values between {@code floorMod} and
      -     * the {@code %} operator is due to the difference between
      -     * {@code floorDiv} that returns the integer less than or equal to the quotient
      -     * and the {@code /} operator that returns the integer closest to zero.
      +     * The difference in values between {@code floorMod} and the {@code %} operator
      +     * is due to the difference between {@code floorDiv} and the {@code /}
      +     * operator, as detailed in {@linkplain #floorDiv(int, int)}.
            * <p>
            * Examples:
            * <ul>
      -     *   <li>If the signs of the arguments are the same, the results
      -     *       of {@code floorMod} and the {@code %} operator are the same.<br>
      +     *   <li>Regardless of the signs of the arguments, {@code floorMod}(x, y)
      +     *       is zero exactly when {@code x % y} is zero as well.</li>
      +     *   <li>If neither of {@code floorMod}(x, y) or {@code x % y} is zero,
      +     *       their results differ exactly when the signs of the arguments differ.<br>
            *       <ul>
            *       <li>{@code floorMod(+4, +3) == +1}; &nbsp; and {@code (+4 % +3) == +1}</li>
            *       <li>{@code floorMod(-4, -3) == -1}; &nbsp; and {@code (-4 % -3) == -1}</li>
      -     *       </ul>
      -     *   <li>If the signs of the arguments are different, the results
      -     *       differ from the {@code %} operator.<br>
      -     *       <ul>
            *       <li>{@code floorMod(+4, -3) == -2}; &nbsp; and {@code (+4 % -3) == +1}</li>
            *       <li>{@code floorMod(-4, +3) == +2}; &nbsp; and {@code (-4 % +3) == -1}</li>
            *       </ul>
      @@ -1385,8 +1384,6 @@
            *   </li>
            * </ul>
            * <p>
      -     * If the signs of arguments are unknown and a positive modulus
      -     * is needed it can be computed as {@code (floorMod(x, y) + abs(y)) % abs(y)}.
            *
            * @param x the dividend
            * @param y the divisor
      @@ -1407,8 +1404,8 @@
           /**
            * Returns the floor modulus of the {@code long} and {@code int} arguments.
            * <p>
      -     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
      -     * has the same sign as the divisor {@code y}, and
      +     * The floor modulus is {@code r = x - (floorDiv(x, y) * y)},
      +     * has the same sign as the divisor {@code y} or is zero, and
            * is in the range of {@code -abs(y) < r < +abs(y)}.
            *
            * <p>
      @@ -1414,7 +1411,7 @@
            * <p>
            * The relationship between {@code floorDiv} and {@code floorMod} is such that:
            * <ul>
      -     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
      +     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}</li>
            * </ul>
            * <p>
            * For examples, see {@link #floorMod(int, int)}.
      @@ -1434,8 +1431,8 @@
           /**
            * Returns the floor modulus of the {@code long} arguments.
            * <p>
      -     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
      -     * has the same sign as the divisor {@code y}, and
      +     * The floor modulus is {@code r = x - (floorDiv(x, y) * y)},
      +     * has the same sign as the divisor {@code y} or is zero, and
            * is in the range of {@code -abs(y) < r < +abs(y)}.
            *
            * <p>
      @@ -1441,7 +1438,7 @@
            * <p>
            * The relationship between {@code floorDiv} and {@code floorMod} is such that:
            * <ul>
      -     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
      +     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}</li>
            * </ul>
            * <p>
            * For examples, see {@link #floorMod(int, int)}.
      
      --- a/src/java.base/share/classes/java/lang/StrictMath.java
      +++ b/src/java.base/share/classes/java/lang/StrictMath.java
      @@ -1051,10 +1051,10 @@
           /**
            * Returns the largest (closest to positive infinity)
            * {@code int} value that is less than or equal to the algebraic quotient.
      -     * There is one special case, if the dividend is the
      +     * 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 the {@code Integer.MIN_VALUE}.
      +     * the result is equal to {@code Integer.MIN_VALUE}.
            * <p>
            * See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
            * a comparison to the integer division {@code /} operator.
      @@ -1075,7 +1075,7 @@
           /**
            * Returns the largest (closest to positive infinity)
            * {@code long} value that is less than or equal to the algebraic quotient.
      -     * There is one special case, if the dividend is the
      +     * 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}.
      @@ -1099,10 +1099,10 @@
           /**
            * Returns the largest (closest to positive infinity)
            * {@code long} value that is less than or equal to the algebraic quotient.
      -     * There is one special case, if the dividend is the
      +     * 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 the {@code Long.MIN_VALUE}.
      +     * the result is equal to {@code Long.MIN_VALUE}.
            * <p>
            * See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
            * a comparison to the integer division {@code /} operator.
      @@ -1123,13 +1123,14 @@
           /**
            * Returns the floor modulus of the {@code int} arguments.
            * <p>
      -     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
      -     * has the same sign as the divisor {@code y}, and
      +     * The floor modulus is {@code r = x - (floorDiv(x, y) * y)},
      +     * has the same 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 floorDiv} and {@code floorMod} is such that:
            * <ul>
      -     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
      +     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}</li>
            * </ul>
            * <p>
            * See {@link Math#floorMod(int, int) Math.floorMod} for examples and
      @@ -1150,8 +1151,8 @@
           /**
            * Returns the floor modulus of the {@code long} and {@code int} arguments.
            * <p>
      -     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
      -     * has the same sign as the divisor {@code y}, and
      +     * The floor modulus is {@code r = x - (floorDiv(x, y) * y)},
      +     * has the same sign as the divisor {@code y} or is zero, and
            * is in the range of {@code -abs(y) < r < +abs(y)}.
            *
            * <p>
      @@ -1157,7 +1158,7 @@
            * <p>
            * The relationship between {@code floorDiv} and {@code floorMod} is such that:
            * <ul>
      -     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
      +     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}</li>
            * </ul>
            * <p>
            * See {@link Math#floorMod(int, int) Math.floorMod} for examples and
      @@ -1178,13 +1179,14 @@
           /**
            * Returns the floor modulus of the {@code long} arguments.
            * <p>
      -     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
      -     * has the same sign as the divisor {@code y}, and
      +     * The floor modulus is {@code r = x - (floorDiv(x, y) * y)},
      +     * has the same 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 floorDiv} and {@code floorMod} is such that:
            * <ul>
      -     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
      +     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}</li>
            * </ul>
            * <p>
            * See {@link Math#floorMod(int, int) Math.floorMod} for examples and

            bpb Brian Burkhalter
            webbuggrp Webbug Group
            Joe Darcy
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved: