JDK-8075806 : divideExact is missing in java.lang.Math
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_8
  • CPU: x86
  • Submitted: 2015-03-22
  • Updated: 2021-08-02
  • Resolved: 2021-07-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 18
18 b08Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
For instance Integer.MIN_VALUE / -1 will overflow, but there is no method divideExact in java.lang.Math. A standardized divideExact would be most helpful, because it would allow to write programs which use well defined methods and shows the overflow is critical without the need to clutter it with (probable undocumented) if statements for this special case.

JUSTIFICATION :
addExact, subtractExact, multiplyExact, incrementExact, decrementExact, and negateExact have been added to java.lang.Math to support arithmetic operations which support overflow detection (even though the documentation doesn't say this for the latter three in the Math documentation). This might suggest that there is no overflow risk with the divide operation. Alone for symmetric reasons the divideExact method should be added.
Additionally the JVM might be able to optimize this method by using a single processor instruction.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Add the following methods to java.lang.Math

int divideExact(int, int)
long divideExact(long, long)


ACTUAL -
The requested methods don't exist.

CUSTOMER SUBMITTED WORKAROUND :
int x = ������, y = ������, z;

if (x == Integer.MIN_VALUE && y == -1) {
    throw new ArithmeticException("integer overflow");
}

z = x / y;

// The other case y == 0 has been omitted, because it is already covered by the JVM
// (with no special case for 0/0).
// See also: Henry S. Warren, Jr.:Hacker's Delight (2nd Ed.), Page 34.



Comments
Changeset: 0b12e7c8 Author: Brian Burkhalter <bpb@openjdk.org> Date: 2021-07-26 17:19:53 +0000 URL: https://git.openjdk.java.net/jdk/commit/0b12e7c82c559f64c8c202bf59ee71f9cbd5a5fa
26-07-2021

I can see that. Definitely less dangerous.
09-07-2021

Certainly the "exact" nomenclature is potentially misleading here. Obviously a true division result can't necessarily be represented as an integer. But the Java '/' operator on int values is defined something like "integer division with truncation toward zero" which always gives a result representable as an int. In this case "exact" would mean that under that definition, the result is always the expected one, with the division MIN_VALUE by -1 throwing instead.
09-07-2021

A difference here as [~darcy] noted above is that we get into generating results which cannot be represented as integers, unlike in the other cases. One possible solution would be public static int divideExact(int dividend, int divisor) { if (dividend == Integer.MIN_VALUE && divisor == -1) throw new ArithmeticException("int overflow"); else if (dividend % divisor != 0) throw new ArithmeticException("fractional quotient"); return dividend / divisor; }
09-07-2021

We did add Math.absExact, incrementExact, and decrement, each of which has exactly one case that throws an exception instead of wrapping around. A similar case could be made for divideExact and perhaps floorDivExact. Also note that the last paragraph of the Math class spec attempts to list all of these "exact" methods so it will need to be updated too.
09-07-2021

The class-level specification of java.lang.Math states "In cases where the size is int or long and overflow errors need to be detected, the methods addExact, subtractExact, multiplyExact, and toIntExact throw an ArithmeticException when the results overflow. For other arithmetic operations such as divide, absolute value, increment, decrement, and negation overflow occurs only with a specific minimum or maximum value and should be checked against the minimum or maximum as appropriate." which explicitly directs how overflow should be detected for the case presented in the issue description. This implies that this issue should be resolved as "Not an Issue."
14-08-2015

On issue of course is that in its normal course of operations divide produces results that are not representation as exact integers (1/2, 1/3, etc.) so a divide-without-overflow would be different than divide-with-no-fractional-results.
24-03-2015