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

XMLWordPrintable

#### Details

• CSR
• Status: Closed
• P4
• Resolution: Approved
• 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``````

#### People Brian Burkhalter Webbug Group
Joe Darcy