mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8271225: Add floorDivExact() method to java.lang.[Strict]Math
Reviewed-by: darcy
This commit is contained in:
parent
e67125512f
commit
e551852801
3 changed files with 205 additions and 3 deletions
|
@ -1012,6 +1012,9 @@ public final class Math {
|
||||||
* <p>
|
* <p>
|
||||||
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
||||||
* (JLS {@jls 15.17.2}).
|
* (JLS {@jls 15.17.2}).
|
||||||
|
* <p>
|
||||||
|
* The built-in remainder operator "{@code %}" is a suitable counterpart
|
||||||
|
* both for this method and for the built-in division operator "{@code /}".
|
||||||
*
|
*
|
||||||
* @param x the dividend
|
* @param x the dividend
|
||||||
* @param y the divisor
|
* @param y the divisor
|
||||||
|
@ -1039,6 +1042,9 @@ public final class Math {
|
||||||
* <p>
|
* <p>
|
||||||
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
||||||
* (JLS {@jls 15.17.2}).
|
* (JLS {@jls 15.17.2}).
|
||||||
|
* <p>
|
||||||
|
* The built-in remainder operator "{@code %}" is a suitable counterpart
|
||||||
|
* both for this method and for the built-in division operator "{@code /}".
|
||||||
*
|
*
|
||||||
* @param x the dividend
|
* @param x the dividend
|
||||||
* @param y the divisor
|
* @param y the divisor
|
||||||
|
@ -1056,6 +1062,80 @@ public final class Math {
|
||||||
throw new ArithmeticException("long overflow");
|
throw new ArithmeticException("long overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the largest (closest to positive infinity)
|
||||||
|
* {@code int} value that is less than or equal to the algebraic quotient.
|
||||||
|
* This method is identical to {@link #floorDiv(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 floor modulus method {@link #floorMod(int,int)} is a suitable
|
||||||
|
* counterpart both for this method and for the {@link #floorDiv(int,int)}
|
||||||
|
* method.
|
||||||
|
* <p>
|
||||||
|
* For examples, see {@link #floorDiv(int, int)}.
|
||||||
|
*
|
||||||
|
* @param x the dividend
|
||||||
|
* @param y the divisor
|
||||||
|
* @return the largest (closest to positive infinity)
|
||||||
|
* {@code int} value that is less 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 #floorDiv(int, int)
|
||||||
|
* @since 18
|
||||||
|
*/
|
||||||
|
public static int floorDivExact(int x, int y) {
|
||||||
|
int r = x / y;
|
||||||
|
if ((x & y & r) >= 0) {
|
||||||
|
// if the signs are different and modulo not zero, round down
|
||||||
|
if ((x ^ y) < 0 && (r * y != x)) {
|
||||||
|
r--;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
throw new ArithmeticException("integer overflow");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the largest (closest to positive infinity)
|
||||||
|
* {@code long} value that is less than or equal to the algebraic quotient.
|
||||||
|
* This method is identical to {@link #floorDiv(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 floor modulus method {@link #floorMod(long,long)} is a suitable
|
||||||
|
* counterpart both for this method and for the {@link #floorDiv(long,long)}
|
||||||
|
* method.
|
||||||
|
* <p>
|
||||||
|
* For examples, see {@link #floorDiv(int, int)}.
|
||||||
|
*
|
||||||
|
* @param x the dividend
|
||||||
|
* @param y the divisor
|
||||||
|
* @return the largest (closest to positive infinity)
|
||||||
|
* {@code long} value that is less 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 #floorDiv(long,long)
|
||||||
|
* @since 18
|
||||||
|
*/
|
||||||
|
public static long floorDivExact(long x, long y) {
|
||||||
|
long r = x / y;
|
||||||
|
if ((x & y & r) >= 0) {
|
||||||
|
// if the signs are different and modulo not zero, round down
|
||||||
|
if ((x ^ y) < 0 && (r * y != x)) {
|
||||||
|
r--;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
throw new ArithmeticException("long overflow");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the argument incremented by one, throwing an exception if the
|
* Returns the argument incremented by one, throwing an exception if the
|
||||||
* result overflows an {@code int}.
|
* result overflows an {@code int}.
|
||||||
|
|
|
@ -863,6 +863,9 @@ public final class StrictMath {
|
||||||
* <p>
|
* <p>
|
||||||
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
||||||
* (JLS {@jls 15.17.2}).
|
* (JLS {@jls 15.17.2}).
|
||||||
|
* <p>
|
||||||
|
* The built-in remainder operator "{@code %}" is a suitable counterpart
|
||||||
|
* both for this method and for the built-in division operator "{@code /}".
|
||||||
*
|
*
|
||||||
* @param x the dividend
|
* @param x the dividend
|
||||||
* @param y the divisor
|
* @param y the divisor
|
||||||
|
@ -887,6 +890,9 @@ public final class StrictMath {
|
||||||
* <p>
|
* <p>
|
||||||
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
* If {@code y} is zero, an {@code ArithmeticException} is thrown
|
||||||
* (JLS {@jls 15.17.2}).
|
* (JLS {@jls 15.17.2}).
|
||||||
|
* <p>
|
||||||
|
* The built-in remainder operator "{@code %}" is a suitable counterpart
|
||||||
|
* both for this method and for the built-in division operator "{@code /}".
|
||||||
*
|
*
|
||||||
* @param x the dividend
|
* @param x the dividend
|
||||||
* @param y the divisor
|
* @param y the divisor
|
||||||
|
@ -901,6 +907,66 @@ public final class StrictMath {
|
||||||
return Math.divideExact(x, y);
|
return Math.divideExact(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the largest (closest to positive infinity)
|
||||||
|
* {@code int} value that is less than or equal to the algebraic quotient.
|
||||||
|
* This method is identical to {@link #floorDiv(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 floor modulus method {@link #floorMod(int,int)} is a suitable
|
||||||
|
* counterpart both for this method and for the {@link #floorDiv(int,int)}
|
||||||
|
* method.
|
||||||
|
* <p>
|
||||||
|
* See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
|
||||||
|
* a comparison to the integer division {@code /} operator.
|
||||||
|
*
|
||||||
|
* @param x the dividend
|
||||||
|
* @param y the divisor
|
||||||
|
* @return the largest (closest to positive infinity)
|
||||||
|
* {@code int} value that is less 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#floorDiv(int, int)
|
||||||
|
* @since 18
|
||||||
|
*/
|
||||||
|
public static int floorDivExact(int x, int y) {
|
||||||
|
return Math.floorDivExact(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the largest (closest to positive infinity)
|
||||||
|
* {@code long} value that is less than or equal to the algebraic quotient.
|
||||||
|
* This method is identical to {@link #floorDiv(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 floor modulus method {@link #floorMod(long,long)} is a suitable
|
||||||
|
* counterpart both for this method and for the {@link #floorDiv(long,long)}
|
||||||
|
* method.
|
||||||
|
* <p>
|
||||||
|
* For examples, see {@link Math#floorDiv(int, int) Math.floorDiv}.
|
||||||
|
*
|
||||||
|
* @param x the dividend
|
||||||
|
* @param y the divisor
|
||||||
|
* @return the largest (closest to positive infinity)
|
||||||
|
* {@code long} value that is less 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#floorDiv(int, int)
|
||||||
|
* @see Math#floorDiv(long,long)
|
||||||
|
* @since 18
|
||||||
|
*/
|
||||||
|
public static long floorDivExact(long x, long y) {
|
||||||
|
return Math.floorDivExact(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the argument incremented by one,
|
* Returns the argument incremented by one,
|
||||||
* throwing an exception if the result overflows an {@code int}.
|
* throwing an exception if the result overflows an {@code int}.
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class ExactArithTests {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
|
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
|
||||||
* incrementExact, decrementExact, negateExact methods with
|
* floorDivExact, incrementExact, decrementExact, negateExact methods with
|
||||||
* {@code int} arguments.
|
* {@code int} arguments.
|
||||||
*/
|
*/
|
||||||
static void testIntegerExact() {
|
static void testIntegerExact() {
|
||||||
|
@ -166,6 +166,34 @@ public class ExactArithTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exceptionExpected = false;
|
||||||
|
try {
|
||||||
|
// Test floorDivExact
|
||||||
|
int q = 0;
|
||||||
|
try {
|
||||||
|
q = Math.floorDiv(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
exceptionExpected = true;
|
||||||
|
}
|
||||||
|
if (!exceptionExpected && x == Integer.MIN_VALUE && y == -1) {
|
||||||
|
exceptionExpected = true;
|
||||||
|
}
|
||||||
|
int z = Math.floorDivExact(x, y);
|
||||||
|
if (exceptionExpected) {
|
||||||
|
fail("FAIL: int Math.floorDivExact(" + x + " / " + y + ")" +
|
||||||
|
"; expected ArithmeticException not thrown");
|
||||||
|
}
|
||||||
|
if (z != q) {
|
||||||
|
fail("FAIL: int Math.floorDivExact(" + x + " / " + y + ") = " +
|
||||||
|
z + "; expected: " + q);
|
||||||
|
}
|
||||||
|
} catch (ArithmeticException ex) {
|
||||||
|
if (!exceptionExpected) {
|
||||||
|
fail("FAIL: int Math.floorDivExact(" + x + " / " + y + ")" +
|
||||||
|
"; Unexpected exception: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Test incrementExact
|
// Test incrementExact
|
||||||
int inc = Math.incrementExact(x);
|
int inc = Math.incrementExact(x);
|
||||||
|
@ -217,8 +245,8 @@ public class ExactArithTests {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
|
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
|
||||||
* incrementExact, decrementExact, negateExact, toIntExact methods
|
* floorDivExact, incrementExact, decrementExact, negateExact, toIntExact
|
||||||
* with {@code long} arguments.
|
* methods with {@code long} arguments.
|
||||||
*/
|
*/
|
||||||
static void testLongExact() {
|
static void testLongExact() {
|
||||||
testLongExactTwice(0, 0);
|
testLongExactTwice(0, 0);
|
||||||
|
@ -324,6 +352,34 @@ public class ExactArithTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean exceptionExpected = false;
|
||||||
|
try {
|
||||||
|
// Test floorDivExact
|
||||||
|
long q = 0;
|
||||||
|
try {
|
||||||
|
q = Math.floorDiv(x, y);
|
||||||
|
} catch (ArithmeticException e) {
|
||||||
|
exceptionExpected = true;
|
||||||
|
}
|
||||||
|
if (!exceptionExpected && x == Long.MIN_VALUE && y == -1) {
|
||||||
|
exceptionExpected = true;
|
||||||
|
}
|
||||||
|
long z = Math.floorDivExact(x, y);
|
||||||
|
if (exceptionExpected) {
|
||||||
|
fail("FAIL: long Math.floorDivExact(" + x + " / " + y + ")" +
|
||||||
|
"; expected ArithmeticException not thrown");
|
||||||
|
}
|
||||||
|
if (z != q) {
|
||||||
|
fail("FAIL: long Math.floorDivExact(" + x + " / " + y + ") = " +
|
||||||
|
z + "; expected: " + q);
|
||||||
|
}
|
||||||
|
} catch (ArithmeticException ex) {
|
||||||
|
if (!exceptionExpected) {
|
||||||
|
fail("FAIL: long Math.floorDivExact(" + x + " / " + y + ")" +
|
||||||
|
"; Unexpected exception: " + ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Test incrementExact
|
// Test incrementExact
|
||||||
resultBig = xBig.add(BigInteger.ONE);
|
resultBig = xBig.add(BigInteger.ONE);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue