8075806: divideExact is missing in java.lang.Math
Reviewed-by: darcy
This commit is contained in:
parent
efa63dc1c6
commit
0b12e7c82c
src/java.base/share/classes/java/lang
test/jdk/java/lang/Math
@ -91,13 +91,8 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||
* will not overflow the range of values of the computation.
|
||||
* The best practice is to choose the primitive type and algorithm to avoid
|
||||
* overflow. In cases where the size is {@code int} or {@code long} and
|
||||
* overflow errors need to be detected, the methods {@code addExact},
|
||||
* {@code subtractExact}, {@code multiplyExact}, {@code toIntExact},
|
||||
* {@code incrementExact}, {@code decrementExact} and {@code negateExact}
|
||||
* throw an {@code ArithmeticException} when the results overflow.
|
||||
* For the arithmetic operations divide and absolute value, overflow
|
||||
* occurs only with a specific minimum or maximum value and
|
||||
* should be checked against the minimum or maximum as appropriate.
|
||||
* overflow errors need to be detected, the methods whose names end with
|
||||
* {@code Exact} throw an {@code ArithmeticException} when the results overflow.
|
||||
*
|
||||
* <h2><a id=Ieee754RecommendedOps>IEEE 754 Recommended
|
||||
* Operations</a></h2>
|
||||
@ -1007,6 +1002,60 @@ public final class Math {
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the arguments, throwing an exception if the
|
||||
* result overflows an {@code int}. Such overflow occurs in this method if
|
||||
* {@code x} is {@link Integer#MIN_VALUE} and {@code y} is {@code -1}.
|
||||
* In contrast, if {@code Integer.MIN_VALUE / -1} were evaluated directly,
|
||||
* the result would be {@code Integer.MIN_VALUE} and no exception would be
|
||||
* thrown.
|
||||
* <p>
|
||||
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
||||
* (JLS {@jls 15.17.2}).
|
||||
*
|
||||
* @param x the dividend
|
||||
* @param y the divisor
|
||||
* @return the quotient {@code x / y}
|
||||
* @throws ArithmeticException if {@code y} is zero or the quotient
|
||||
* overflows an int
|
||||
* @jls 15.17.2 Division Operator /
|
||||
* @since 18
|
||||
*/
|
||||
public static int divideExact(int x, int y) {
|
||||
int q = x / y;
|
||||
if ((x & y & q) >= 0) {
|
||||
return q;
|
||||
}
|
||||
throw new ArithmeticException("integer overflow");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the arguments, throwing an exception if the
|
||||
* result overflows a {@code long}. Such overflow occurs in this method if
|
||||
* {@code x} is {@link Long#MIN_VALUE} and {@code y} is {@code -1}.
|
||||
* In contrast, if {@code Long.MIN_VALUE / -1} were evaluated directly,
|
||||
* the result would be {@code Long.MIN_VALUE} and no exception would be
|
||||
* thrown.
|
||||
* <p>
|
||||
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
||||
* (JLS {@jls 15.17.2}).
|
||||
*
|
||||
* @param x the dividend
|
||||
* @param y the divisor
|
||||
* @return the quotient {@code x / y}
|
||||
* @throws ArithmeticException if {@code y} is zero or the quotient
|
||||
* overflows a long
|
||||
* @jls 15.17.2 Division Operator /
|
||||
* @since 18
|
||||
*/
|
||||
public static long divideExact(long x, long y) {
|
||||
long q = x / y;
|
||||
if ((x & y & q) >= 0) {
|
||||
return q;
|
||||
}
|
||||
throw new ArithmeticException("long overflow");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the argument incremented by one, throwing an exception if the
|
||||
* result overflows an {@code int}.
|
||||
|
@ -66,13 +66,8 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||
* will not overflow the range of values of the computation.
|
||||
* The best practice is to choose the primitive type and algorithm to avoid
|
||||
* overflow. In cases where the size is {@code int} or {@code long} and
|
||||
* overflow errors need to be detected, the methods {@code addExact},
|
||||
* {@code subtractExact}, {@code multiplyExact}, {@code toIntExact},
|
||||
* {@code incrementExact}, {@code decrementExact} and {@code negateExact}
|
||||
* throw an {@code ArithmeticException} when the results overflow.
|
||||
* For the arithmetic operations divide and absolute value, overflow
|
||||
* occurs only with a specific minimum or maximum value and
|
||||
* should be checked against the minimum or maximum as appropriate.
|
||||
* overflow errors need to be detected, the methods whose names end with
|
||||
* {@code Exact} throw an {@code ArithmeticException} when the results overflow.
|
||||
*
|
||||
* <h2><a id=Ieee754RecommendedOps>IEEE 754 Recommended
|
||||
* Operations</a></h2>
|
||||
@ -858,6 +853,54 @@ public final class StrictMath {
|
||||
return Math.multiplyExact(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the arguments, throwing an exception if the
|
||||
* result overflows an {@code int}. Such overflow occurs in this method if
|
||||
* {@code x} is {@link Integer#MIN_VALUE} and {@code y} is {@code -1}.
|
||||
* In contrast, if {@code Integer.MIN_VALUE / -1} were evaluated directly,
|
||||
* the result would be {@code Integer.MIN_VALUE} and no exception would be
|
||||
* thrown.
|
||||
* <p>
|
||||
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
||||
* (JLS {@jls 15.17.2}).
|
||||
*
|
||||
* @param x the dividend
|
||||
* @param y the divisor
|
||||
* @return the quotient {@code x / y}
|
||||
* @throws ArithmeticException if {@code y} is zero or the quotient
|
||||
* overflows an int
|
||||
* @jls 15.17.2 Division Operator /
|
||||
* @see Math#divideExact(int,int)
|
||||
* @since 18
|
||||
*/
|
||||
public static int divideExact(int x, int y) {
|
||||
return Math.divideExact(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the quotient of the arguments, throwing an exception if the
|
||||
* result overflows a {@code long}. Such overflow occurs in this method if
|
||||
* {@code x} is {@link Long#MIN_VALUE} and {@code y} is {@code -1}.
|
||||
* In contrast, if {@code Long.MIN_VALUE / -1} were evaluated directly,
|
||||
* the result would be {@code Long.MIN_VALUE} and no exception would be
|
||||
* thrown.
|
||||
* <p>
|
||||
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
||||
* (JLS {@jls 15.17.2}).
|
||||
*
|
||||
* @param x the dividend
|
||||
* @param y the divisor
|
||||
* @return the quotient {@code x / y}
|
||||
* @throws ArithmeticException if {@code y} is zero or the quotient
|
||||
* overflows a long
|
||||
* @jls 15.17.2 Division Operator /
|
||||
* @see Math#divideExact(long,long)
|
||||
* @since 18
|
||||
*/
|
||||
public static long divideExact(long x, long y) {
|
||||
return Math.divideExact(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the argument incremented by one,
|
||||
* throwing an exception if the result overflows an {@code int}.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,7 +25,7 @@ import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* @test Test for Math.*Exact integer and long methods.
|
||||
* @bug 6708398
|
||||
* @bug 6708398 8075806
|
||||
* @summary Basic tests for Math exact arithmetic operations.
|
||||
*
|
||||
* @author Roger Riggs
|
||||
@ -56,8 +56,9 @@ public class ExactArithTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Math.addExact, multiplyExact, subtractExact, incrementExact,
|
||||
* decrementExact, negateExact methods with {@code int} arguments.
|
||||
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
|
||||
* incrementExact, decrementExact, negateExact methods with
|
||||
* {@code int} arguments.
|
||||
*/
|
||||
static void testIntegerExact() {
|
||||
testIntegerExact(0, 0);
|
||||
@ -132,6 +133,39 @@ public class ExactArithTests {
|
||||
}
|
||||
}
|
||||
|
||||
boolean exceptionExpected = false;
|
||||
try {
|
||||
// Test divideExact
|
||||
BigInteger q = null;
|
||||
try {
|
||||
q = BigInteger.valueOf(x).divide(BigInteger.valueOf(y));
|
||||
} catch (ArithmeticException e) {
|
||||
exceptionExpected = true;
|
||||
}
|
||||
int quotient = 0;
|
||||
if (q != null) {
|
||||
try {
|
||||
quotient = q.intValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
exceptionExpected = true;
|
||||
}
|
||||
}
|
||||
int z = Math.divideExact(x, y);
|
||||
if (exceptionExpected) {
|
||||
fail("FAIL: int Math.divideExact(" + x + " / " + y + ")" +
|
||||
"; expected ArithmeticException not thrown");
|
||||
}
|
||||
if (z != quotient) {
|
||||
fail("FAIL: int Math.divideExact(" + x + " / " + y + ") = " +
|
||||
z + "; expected: " + quotient);
|
||||
}
|
||||
} catch (ArithmeticException ex) {
|
||||
if (!exceptionExpected) {
|
||||
fail("FAIL: int Math.divideExact(" + x + " / " + y + ")" +
|
||||
"; Unexpected exception: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Test incrementExact
|
||||
int inc = Math.incrementExact(x);
|
||||
@ -182,8 +216,9 @@ public class ExactArithTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Math.addExact, multiplyExact, subtractExact, incrementExact,
|
||||
* decrementExact, negateExact, toIntExact methods with {@code long} arguments.
|
||||
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
|
||||
* incrementExact, decrementExact, negateExact, toIntExact methods
|
||||
* with {@code long} arguments.
|
||||
*/
|
||||
static void testLongExact() {
|
||||
testLongExactTwice(0, 0);
|
||||
@ -269,6 +304,26 @@ public class ExactArithTests {
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Test divideExact
|
||||
resultBig = null;
|
||||
try {
|
||||
resultBig = xBig.divide(yBig);
|
||||
} catch (ArithmeticException ex) {
|
||||
}
|
||||
long quotient = Math.divideExact(x, y);
|
||||
if (resultBig == null) {
|
||||
fail("FAIL: long Math.divideExact(" + x + " / " + y + ")" +
|
||||
"; expected ArithmeticException not thrown");
|
||||
}
|
||||
checkResult("long Math.divideExact", x, y, quotient, resultBig);
|
||||
} catch (ArithmeticException ex) {
|
||||
if (resultBig != null && inLongRange(resultBig)) {
|
||||
fail("FAIL: long Math.divideExact(" + x + " / " + y + ")" +
|
||||
"; Unexpected exception: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Test incrementExact
|
||||
resultBig = xBig.add(BigInteger.ONE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user