8271602: Add Math.ceilDiv() family parallel to Math.floorDiv() family

Reviewed-by: bpb
This commit is contained in:
Raffaello Giulietti 2021-09-22 16:16:14 +00:00 committed by Brian Burkhalter
parent d39aad9230
commit da38ced329
4 changed files with 1093 additions and 53 deletions

View File

@ -1088,13 +1088,13 @@ public final class Math {
* @since 18
*/
public static int floorDivExact(int x, int y) {
int r = x / y;
if ((x & y & r) >= 0) {
final int q = x / y;
if ((x & y & q) >= 0) {
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
if ((x ^ y) < 0 && (q * y != x)) {
return q - 1;
}
return r;
return q;
}
throw new ArithmeticException("integer overflow");
}
@ -1125,13 +1125,87 @@ public final class Math {
* @since 18
*/
public static long floorDivExact(long x, long y) {
long r = x / y;
if ((x & y & r) >= 0) {
final long q = x / y;
if ((x & y & q) >= 0) {
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
if ((x ^ y) < 0 && (q * y != x)) {
return q - 1;
}
return r;
return q;
}
throw new ArithmeticException("long overflow");
}
/**
* Returns the smallest (closest to negative infinity)
* {@code int} value that is greater than or equal to the algebraic quotient.
* This method is identical to {@link #ceilDiv(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 ceil modulus method {@link #ceilMod(int,int)} is a suitable
* counterpart both for this method and for the {@link #ceilDiv(int,int)}
* method.
* <p>
* For examples, see {@link #ceilDiv(int, int)}.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code int} value that is greater 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 #ceilDiv(int, int)
* @since 18
*/
public static int ceilDivExact(int x, int y) {
final int q = x / y;
if ((x & y & q) >= 0) {
// if the signs are the same and modulo not zero, round up
if ((x ^ y) >= 0 && (q * y != x)) {
return q + 1;
}
return q;
}
throw new ArithmeticException("integer overflow");
}
/**
* Returns the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* This method is identical to {@link #ceilDiv(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 ceil modulus method {@link #ceilMod(long,long)} is a suitable
* counterpart both for this method and for the {@link #ceilDiv(long,long)}
* method.
* <p>
* For examples, see {@link #ceilDiv(int, int)}.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code long} value that is greater 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 #ceilDiv(long,long)
* @since 18
*/
public static long ceilDivExact(long x, long y) {
final long q = x / y;
if ((x & y & q) >= 0) {
// if the signs are the same and modulo not zero, round up
if ((x ^ y) >= 0 && (q * y != x)) {
return q + 1;
}
return q;
}
throw new ArithmeticException("long overflow");
}
@ -1361,12 +1435,12 @@ public final class Math {
* @since 1.8
*/
public static int floorDiv(int x, int y) {
int r = x / y;
final int q = x / y;
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
if ((x ^ y) < 0 && (q * y != x)) {
return q - 1;
}
return r;
return q;
}
/**
@ -1424,12 +1498,12 @@ public final class Math {
* @since 1.8
*/
public static long floorDiv(long x, long y) {
long r = x / y;
final long q = x / y;
// if the signs are different and modulo not zero, round down
if ((x ^ y) < 0 && (r * y != x)) {
r--;
if ((x ^ y) < 0 && (q * y != x)) {
return q - 1;
}
return r;
return q;
}
/**
@ -1453,8 +1527,8 @@ public final class Math {
* <ul>
* <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>
* <li>If neither {@code floorMod}(x, y) nor {@code x % y} is zero,
* they 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>
@ -1472,12 +1546,12 @@ public final class Math {
* @since 1.8
*/
public static int floorMod(int x, int y) {
int mod = x % y;
final int r = x % y;
// if the signs are different and modulo not zero, adjust result
if ((x ^ y) < 0 && mod != 0) {
mod += y;
if ((x ^ y) < 0 && r != 0) {
return r + y;
}
return mod;
return r;
}
/**
@ -1530,12 +1604,226 @@ public final class Math {
* @since 1.8
*/
public static long floorMod(long x, long y) {
long mod = x % y;
final long r = x % y;
// if the signs are different and modulo not zero, adjust result
if ((x ^ y) < 0 && mod != 0) {
mod += y;
if ((x ^ y) < 0 && r != 0) {
return r + y;
}
return mod;
return r;
}
/**
* Returns the smallest (closest to negative infinity)
* {@code int} value that is greater than or equal to the algebraic quotient.
* 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}.
* <p>
* Normal integer division operates under the round to zero rounding mode
* (truncation). This operation instead acts under the round toward
* positive infinity (ceiling) rounding mode.
* The ceiling rounding mode gives different results from truncation
* when the exact quotient is not an integer and is positive.
* <ul>
* <li>If the signs of the arguments are different, the results of
* {@code ceilDiv} and the {@code /} operator are the same. <br>
* For example, {@code ceilDiv(-4, 3) == -1} and {@code (-4 / 3) == -1}.</li>
* <li>If the signs of the arguments are the same, {@code ceilDiv}
* returns the smallest integer greater than or equal to the quotient
* while the {@code /} operator returns the largest integer less
* than or equal to the quotient.
* They differ if and only if the quotient is not an integer.<br>
* For example, {@code ceilDiv(4, 3) == 2},
* whereas {@code (4 / 3) == 1}.
* </li>
* </ul>
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code int} value that is greater than or equal to the algebraic quotient.
* @throws ArithmeticException if the divisor {@code y} is zero
* @see #ceilMod(int, int)
* @see #ceil(double)
* @since 18
*/
public static int ceilDiv(int x, int y) {
final int q = x / y;
// if the signs are the same and modulo not zero, round up
if ((x ^ y) >= 0 && (q * y != x)) {
return q + 1;
}
return q;
}
/**
* Returns the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* 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}.
* <p>
* Normal integer division operates under the round to zero rounding mode
* (truncation). This operation instead acts under the round toward
* positive infinity (ceiling) rounding mode.
* The ceiling rounding mode gives different results from truncation
* when the exact result is not an integer and is positive.
* <p>
* For examples, see {@link #ceilDiv(int, int)}.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* @throws ArithmeticException if the divisor {@code y} is zero
* @see #ceilMod(int, int)
* @see #ceil(double)
* @since 18
*/
public static long ceilDiv(long x, int y) {
return ceilDiv(x, (long)y);
}
/**
* Returns the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* 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}.
* <p>
* Normal integer division operates under the round to zero rounding mode
* (truncation). This operation instead acts under the round toward
* positive infinity (ceiling) rounding mode.
* The ceiling rounding mode gives different results from truncation
* when the exact result is not an integer and is positive.
* <p>
* For examples, see {@link #ceilDiv(int, int)}.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* @throws ArithmeticException if the divisor {@code y} is zero
* @see #ceilMod(int, int)
* @see #ceil(double)
* @since 18
*/
public static long ceilDiv(long x, long y) {
final long q = x / y;
// if the signs are the same and modulo not zero, round up
if ((x ^ y) >= 0 && (q * y != x)) {
return q + 1;
}
return q;
}
/**
* Returns the ceiling modulus of the {@code int} arguments.
* <p>
* The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
* has the opposite 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 ceilDiv} and {@code ceilMod} is such that:
* <ul>
* <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
* </ul>
* <p>
* The difference in values between {@code ceilMod} and the {@code %} operator
* is due to the difference between {@code ceilDiv} and the {@code /}
* operator, as detailed in {@linkplain #ceilDiv(int, int)}.
* <p>
* Examples:
* <ul>
* <li>Regardless of the signs of the arguments, {@code ceilMod}(x, y)
* is zero exactly when {@code x % y} is zero as well.</li>
* <li>If neither {@code ceilMod}(x, y) nor {@code x % y} is zero,
* they differ exactly when the signs of the arguments are the same.<br>
* <ul>
* <li>{@code ceilMod(+4, +3) == -2}; &nbsp; and {@code (+4 % +3) == +1}</li>
* <li>{@code ceilMod(-4, -3) == +2}; &nbsp; and {@code (-4 % -3) == -1}</li>
* <li>{@code ceilMod(+4, -3) == +1}; &nbsp; and {@code (+4 % -3) == +1}</li>
* <li>{@code ceilMod(-4, +3) == -1}; &nbsp; and {@code (-4 % +3) == -1}</li>
* </ul>
* </li>
* </ul>
*
* @param x the dividend
* @param y the divisor
* @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
* @throws ArithmeticException if the divisor {@code y} is zero
* @see #ceilDiv(int, int)
* @since 18
*/
public static int ceilMod(int x, int y) {
final int r = x % y;
// if the signs are the same and modulo not zero, adjust result
if ((x ^ y) >= 0 && r != 0) {
return r - y;
}
return r;
}
/**
* Returns the ceiling modulus of the {@code long} and {@code int} arguments.
* <p>
* The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
* has the opposite 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 ceilDiv} and {@code ceilMod} is such that:
* <ul>
* <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
* </ul>
* <p>
* For examples, see {@link #ceilMod(int, int)}.
*
* @param x the dividend
* @param y the divisor
* @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
* @throws ArithmeticException if the divisor {@code y} is zero
* @see #ceilDiv(long, int)
* @since 18
*/
public static int ceilMod(long x, int y) {
// Result cannot overflow the range of int.
return (int)ceilMod(x, (long)y);
}
/**
* Returns the ceiling modulus of the {@code long} arguments.
* <p>
* The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
* has the opposite 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 ceilDiv} and {@code ceilMod} is such that:
* <ul>
* <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
* </ul>
* <p>
* For examples, see {@link #ceilMod(int, int)}.
*
* @param x the dividend
* @param y the divisor
* @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
* @throws ArithmeticException if the divisor {@code y} is zero
* @see #ceilDiv(long, long)
* @since 18
*/
public static long ceilMod(long x, long y) {
final long r = x % y;
// if the signs are the same and modulo not zero, adjust result
if ((x ^ y) >= 0 && r != 0) {
return r - y;
}
return r;
}
/**

View File

@ -967,6 +967,66 @@ public final class StrictMath {
return Math.floorDivExact(x, y);
}
/**
* Returns the smallest (closest to negative infinity)
* {@code int} value that is greater than or equal to the algebraic quotient.
* This method is identical to {@link #ceilDiv(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 ceil modulus method {@link #ceilMod(int,int)} is a suitable
* counterpart both for this method and for the {@link #ceilDiv(int,int)}
* method.
* <p>
* See {@link Math#ceilDiv(int, int) Math.ceilDiv} for examples and
* a comparison to the integer division {@code /} operator.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code int} value that is greater 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#ceilDiv(int, int)
* @since 18
*/
public static int ceilDivExact(int x, int y) {
return Math.ceilDivExact(x, y);
}
/**
* Returns the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* This method is identical to {@link #ceilDiv(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 ceil modulus method {@link #ceilMod(long,long)} is a suitable
* counterpart both for this method and for the {@link #ceilDiv(long,long)}
* method.
* <p>
* For examples, see {@link Math#ceilDiv(int, int) Math.ceilDiv}.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code long} value that is greater 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#ceilDiv(int, int)
* @see Math#ceilDiv(long,long)
* @since 18
*/
public static long ceilDivExact(long x, long y) {
return Math.ceilDivExact(x, y);
}
/**
* Returns the argument incremented by one,
* throwing an exception if the result overflows an {@code int}.
@ -1270,6 +1330,162 @@ public final class StrictMath {
return Math.floorMod(x, y);
}
/**
* Returns the smallest (closest to negative infinity)
* {@code int} value that is greater than or equal to the algebraic quotient.
* 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}.
* <p>
* See {@link Math#ceilDiv(int, int) Math.ceilDiv} for examples and
* a comparison to the integer division {@code /} operator.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code int} value that is greater than or equal to the algebraic quotient.
* @throws ArithmeticException if the divisor {@code y} is zero
* @see Math#ceilDiv(int, int)
* @see Math#ceil(double)
* @since 18
*/
public static int ceilDiv(int x, int y) {
return Math.ceilDiv(x, y);
}
/**
* Returns the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* 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}.
* <p>
* See {@link Math#ceilDiv(int, int) Math.ceilDiv} for examples and
* a comparison to the integer division {@code /} operator.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* @throws ArithmeticException if the divisor {@code y} is zero
* @see Math#ceilDiv(long, int)
* @see Math#ceil(double)
* @since 18
*/
public static long ceilDiv(long x, int y) {
return Math.ceilDiv(x, y);
}
/**
* Returns the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* 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}.
* <p>
* See {@link Math#ceilDiv(int, int) Math.ceilDiv} for examples and
* a comparison to the integer division {@code /} operator.
*
* @param x the dividend
* @param y the divisor
* @return the smallest (closest to negative infinity)
* {@code long} value that is greater than or equal to the algebraic quotient.
* @throws ArithmeticException if the divisor {@code y} is zero
* @see Math#ceilDiv(long, long)
* @see Math#ceil(double)
* @since 18
*/
public static long ceilDiv(long x, long y) {
return Math.ceilDiv(x, y);
}
/**
* Returns the ceiling modulus of the {@code int} arguments.
* <p>
* The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
* has the opposite 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 ceilDiv} and {@code ceilMod} is such that:
* <ul>
* <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
* </ul>
* <p>
* See {@link Math#ceilMod(int, int) Math.ceilMod} for examples and
* a comparison to the {@code %} operator.
*
* @param x the dividend
* @param y the divisor
* @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
* @throws ArithmeticException if the divisor {@code y} is zero
* @see Math#ceilMod(int, int)
* @see StrictMath#ceilDiv(int, int)
* @since 18
*/
public static int ceilMod(int x, int y) {
return Math.ceilMod(x , y);
}
/**
* Returns the ceiling modulus of the {@code long} and {@code int} arguments.
* <p>
* The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
* has the opposite 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 ceilDiv} and {@code ceilMod} is such that:
* <ul>
* <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
* </ul>
* <p>
* See {@link Math#ceilMod(int, int) Math.ceilMod} for examples and
* a comparison to the {@code %} operator.
*
* @param x the dividend
* @param y the divisor
* @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
* @throws ArithmeticException if the divisor {@code y} is zero
* @see Math#ceilMod(long, int)
* @see StrictMath#ceilDiv(long, int)
* @since 18
*/
public static int ceilMod(long x, int y) {
return Math.ceilMod(x , y);
}
/**
* Returns the ceiling modulus of the {@code long} arguments.
* <p>
* The ceiling modulus is {@code r = x - (ceilDiv(x, y) * y)},
* has the opposite 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 ceilDiv} and {@code ceilMod} is such that:
* <ul>
* <li>{@code ceilDiv(x, y) * y + ceilMod(x, y) == x}</li>
* </ul>
* <p>
* See {@link Math#ceilMod(int, int) Math.ceilMod} for examples and
* a comparison to the {@code %} operator.
*
* @param x the dividend
* @param y the divisor
* @return the ceiling modulus {@code x - (ceilDiv(x, y) * y)}
* @throws ArithmeticException if the divisor {@code y} is zero
* @see Math#ceilMod(long, long)
* @see StrictMath#ceilDiv(long, long)
* @since 18
*/
public static long ceilMod(long x, long y) {
return Math.ceilMod(x, y);
}
/**
* Returns the absolute value of an {@code int} value.
* If the argument is not negative, the argument is returned.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, 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,9 +25,9 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* @test Test Math and StrictMath Floor Div / Modulo operations.
* @bug 6282196
* @summary Basic tests for Floor division and modulo methods for both Math
* @test Test Math and StrictMath Floor and Ceil Div / Modulo operations.
* @bug 6282196 8271602
* @summary Basic tests for Floor and Ceil division and modulo methods for both Math
* and StrictMath for int and long datatypes.
*/
public class DivModTests {
@ -43,7 +43,11 @@ public class DivModTests {
public static void main(String[] args) {
errors = 0;
testIntFloorDivMod();
testLongIntFloorDivMod();
testLongFloorDivMod();
testIntCeilDivMod();
testLongIntCeilDivMod();
testLongCeilDivMod();
if (errors > 0) {
throw new RuntimeException(errors + " errors found in DivMod methods.");
@ -284,19 +288,19 @@ public class DivModTests {
testLongIntFloorDivMod(-3L, -3, 1L, 0);
testLongIntFloorDivMod(-4L, -3, 1L, -1);
testLongIntFloorDivMod(Long.MAX_VALUE, 1, Long.MAX_VALUE, 0L);
testLongIntFloorDivMod(Long.MAX_VALUE, -1, -Long.MAX_VALUE, 0L);
testLongIntFloorDivMod(Long.MAX_VALUE, 3, Long.MAX_VALUE / 3L, 1L);
testLongIntFloorDivMod(Long.MAX_VALUE - 1L, 3, (Long.MAX_VALUE - 1L) / 3L, 0L);
testLongIntFloorDivMod(Long.MIN_VALUE, 3, Long.MIN_VALUE / 3L - 1L, 1L);
testLongIntFloorDivMod(Long.MIN_VALUE + 1L, 3, Long.MIN_VALUE / 3L - 1L, 2L);
testLongIntFloorDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0L);
testLongIntFloorDivMod(Long.MAX_VALUE, 1, Long.MAX_VALUE, 0);
testLongIntFloorDivMod(Long.MAX_VALUE, -1, -Long.MAX_VALUE, 0);
testLongIntFloorDivMod(Long.MAX_VALUE, 3, Long.MAX_VALUE / 3L, 1);
testLongIntFloorDivMod(Long.MAX_VALUE - 1L, 3, (Long.MAX_VALUE - 1L) / 3L, 0);
testLongIntFloorDivMod(Long.MIN_VALUE, 3, Long.MIN_VALUE / 3L - 1L, 1);
testLongIntFloorDivMod(Long.MIN_VALUE + 1L, 3, Long.MIN_VALUE / 3L - 1L, 2);
testLongIntFloorDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0);
testLongIntFloorDivMod(Long.MAX_VALUE, Integer.MAX_VALUE, 4294967298L, 1);
testLongIntFloorDivMod(Long.MAX_VALUE, Integer.MIN_VALUE, -4294967296L, -1);
testLongIntFloorDivMod(Long.MIN_VALUE, Integer.MIN_VALUE, 4294967296L, 0);
testLongIntFloorDivMod(Long.MIN_VALUE, Integer.MAX_VALUE, -4294967299L, 2147483645);
// Special case of integer overflow
testLongIntFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0L);
testLongIntFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0);
}
/**
@ -341,12 +345,12 @@ public class DivModTests {
static void testLongIntFloorMod(long x, int y, Object expected) {
Object result = doFloorMod(x, y);
if (!resultEquals(result, expected)) {
fail("FAIL: long Math.floorMod(%d, %d) = %s; expected %s%n", x, y, result, expected);
fail("FAIL: int Math.floorMod(%d, %d) = %s; expected %s%n", x, y, result, expected);
}
Object strict_result = doStrictFloorMod(x, y);
if (!resultEquals(strict_result, expected)) {
fail("FAIL: long StrictMath.floorMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
fail("FAIL: int StrictMath.floorMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
}
try {
@ -356,7 +360,7 @@ public class DivModTests {
BigDecimal resultD = xD.divide(yD, RoundingMode.FLOOR);
resultD = resultD.multiply(yD);
resultD = xD.subtract(resultD);
long fr = resultD.longValue();
int fr = resultD.intValue();
if (!result.equals(fr)) {
fail("FAIL: Long.floorMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr);
@ -411,7 +415,7 @@ public class DivModTests {
}
/**
* Invoke floorDiv and return the result or any exception.
* Invoke floorMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
@ -425,7 +429,7 @@ public class DivModTests {
}
/**
* Invoke floorDiv and return the result or any exception.
* Invoke floorMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
@ -439,7 +443,7 @@ public class DivModTests {
}
/**
* Invoke floorDiv and return the result or any exception.
* Invoke floorMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
@ -495,7 +499,7 @@ public class DivModTests {
}
/**
* Invoke floorDiv and return the result or any exception.
* Invoke floorMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
@ -509,7 +513,7 @@ public class DivModTests {
}
/**
* Invoke floorDiv and return the result or any exception.
* Invoke floorMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
@ -523,7 +527,7 @@ public class DivModTests {
}
/**
* Invoke floorDiv and return the result or any exception.
* Invoke floorMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
@ -536,6 +540,482 @@ public class DivModTests {
}
}
/**
* Test the integer ceilDiv and ceilMod methods.
* Math and StrictMath tested and the same results are expected for both.
*/
static void testIntCeilDivMod() {
testIntCeilDivMod(4, 0, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException
testIntCeilDivMod(4, 3, 2, -2);
testIntCeilDivMod(3, 3, 1, 0);
testIntCeilDivMod(2, 3, 1, -1);
testIntCeilDivMod(1, 3, 1, -2);
testIntCeilDivMod(0, 3, 0, 0);
testIntCeilDivMod(4, -3, -1, 1);
testIntCeilDivMod(3, -3, -1, 0);
testIntCeilDivMod(2, -3, 0, 2);
testIntCeilDivMod(1, -3, 0, 1);
testIntCeilDivMod(0, -3, 0, 0);
testIntCeilDivMod(-1, 3, 0, -1);
testIntCeilDivMod(-2, 3, 0, -2);
testIntCeilDivMod(-3, 3, -1, 0);
testIntCeilDivMod(-4, 3, -1, -1);
testIntCeilDivMod(-1, -3, 1, 2);
testIntCeilDivMod(-2, -3, 1, 1);
testIntCeilDivMod(-3, -3, 1, 0);
testIntCeilDivMod(-4, -3, 2, 2);
testIntCeilDivMod(Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
testIntCeilDivMod(Integer.MAX_VALUE, -1, -Integer.MAX_VALUE, 0);
testIntCeilDivMod(Integer.MAX_VALUE, 3, 715_827_883, -2);
testIntCeilDivMod(Integer.MAX_VALUE - 1, 3, 715_827_882, 0);
testIntCeilDivMod(Integer.MIN_VALUE, 3, -715_827_882, -2);
testIntCeilDivMod(Integer.MIN_VALUE + 1, 3, -715_827_882, -1);
testIntCeilDivMod(Integer.MIN_VALUE + 1, -1, Integer.MAX_VALUE, 0);
testIntCeilDivMod(Integer.MAX_VALUE, Integer.MAX_VALUE, 1, 0);
testIntCeilDivMod(Integer.MAX_VALUE, Integer.MIN_VALUE, 0, Integer.MAX_VALUE);
testIntCeilDivMod(Integer.MIN_VALUE, Integer.MIN_VALUE, 1, 0);
testIntCeilDivMod(Integer.MIN_VALUE, Integer.MAX_VALUE, -1, -1);
// Special case of integer overflow
testIntCeilDivMod(Integer.MIN_VALUE, -1, Integer.MIN_VALUE, 0);
}
/**
* Test CeilDiv and then CeilMod with int data.
*/
static void testIntCeilDivMod(int x, int y, Object divExpected, Object modExpected) {
testIntCeilDiv(x, y, divExpected);
testIntCeilMod(x, y, modExpected);
}
/**
* Test CeilDiv with int data.
*/
static void testIntCeilDiv(int x, int y, Object expected) {
Object result = doCeilDiv(x, y);
if (!resultEquals(result, expected)) {
fail("FAIL: Math.ceilDiv(%d, %d) = %s; expected %s%n", x, y, result, expected);
}
Object strict_result = doStrictCeilDiv(x, y);
if (!resultEquals(strict_result, expected)) {
fail("FAIL: StrictMath.ceilDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
}
}
/**
* Test CeilMod with int data.
*/
static void testIntCeilMod(int x, int y, Object expected) {
Object result = doCeilMod(x, y);
if (!resultEquals(result, expected)) {
fail("FAIL: Math.ceilMod(%d, %d) = %s; expected %s%n", x, y, result, expected);
}
Object strict_result = doStrictCeilMod(x, y);
if (!resultEquals(strict_result, expected)) {
fail("FAIL: StrictMath.ceilMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
}
try {
// Verify result against double precision ceil function
int tmp = x / y; // Force ArithmeticException for divide by zero
double ff = x - Math.ceil((double)x / (double)y) * y;
int fr = (int)ff;
boolean t = (fr == ((Integer)result));
if (!result.equals(fr)) {
fail("FAIL: Math.ceilMod(%d, %d) = %s differs from Math.ceil(x, y): %d%n", x, y, result, fr);
}
} catch (ArithmeticException ae) {
if (y != 0) {
fail("FAIL: Math.ceilMod(%d, %d); unexpected %s%n", x, y, ae);
}
}
}
/**
* Test the ceilDiv and ceilMod methods for primitive long.
*/
static void testLongCeilDivMod() {
testLongCeilDivMod(4L, 0L, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException
testLongCeilDivMod(4L, 3L, 2L, -2L);
testLongCeilDivMod(3L, 3L, 1L, 0L);
testLongCeilDivMod(2L, 3L, 1L, -1L);
testLongCeilDivMod(1L, 3L, 1L, -2L);
testLongCeilDivMod(0L, 3L, 0L, 0L);
testLongCeilDivMod(4L, -3L, -1L, 1L);
testLongCeilDivMod(3L, -3L, -1L, 0L);
testLongCeilDivMod(2L, -3L, 0L, 2L);
testLongCeilDivMod(1L, -3L, 0L, 1L);
testLongCeilDivMod(0L, -3L, 0L, 0L);
testLongCeilDivMod(-1L, 3L, 0L, -1L);
testLongCeilDivMod(-2L, 3L, 0L, -2L);
testLongCeilDivMod(-3L, 3L, -1L, 0L);
testLongCeilDivMod(-4L, 3L, -1L, -1L);
testLongCeilDivMod(-1L, -3L, 1L, 2L);
testLongCeilDivMod(-2L, -3L, 1L, 1L);
testLongCeilDivMod(-3L, -3L, 1L, 0L);
testLongCeilDivMod(-4L, -3L, 2L, 2L);
testLongCeilDivMod(Long.MAX_VALUE, 1, Long.MAX_VALUE, 0L);
testLongCeilDivMod(Long.MAX_VALUE, -1, -Long.MAX_VALUE, 0L);
testLongCeilDivMod(Long.MAX_VALUE, 3L, Long.MAX_VALUE / 3L + 1, -2L);
testLongCeilDivMod(Long.MAX_VALUE - 1L, 3L, (Long.MAX_VALUE - 1L) / 3L, 0L);
testLongCeilDivMod(Long.MIN_VALUE, 3L, Long.MIN_VALUE / 3L, -2L);
testLongCeilDivMod(Long.MIN_VALUE + 1L, 3L, Long.MIN_VALUE / 3L, -1L);
testLongCeilDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0L);
testLongCeilDivMod(Long.MAX_VALUE, Long.MAX_VALUE, 1L, 0L);
testLongCeilDivMod(Long.MAX_VALUE, Long.MIN_VALUE, 0L, Long.MAX_VALUE);
testLongCeilDivMod(Long.MIN_VALUE, Long.MIN_VALUE, 1L, 0L);
testLongCeilDivMod(Long.MIN_VALUE, Long.MAX_VALUE, -1L, -1L);
// Special case of integer overflow
testLongCeilDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0L);
}
/**
* Test the long ceilDiv and ceilMod methods.
* Math and StrictMath are tested and the same results are expected for both.
*/
static void testLongCeilDivMod(long x, long y, Object divExpected, Object modExpected) {
testLongCeilDiv(x, y, divExpected);
testLongCeilMod(x, y, modExpected);
}
/**
* Test CeilDiv with long arguments against expected value.
* The expected value is usually a Long but in some cases is
* an ArithmeticException.
*
* @param x dividend
* @param y modulus
* @param expected expected value,
*/
static void testLongCeilDiv(long x, long y, Object expected) {
Object result = doCeilDiv(x, y);
if (!resultEquals(result, expected)) {
fail("FAIL: long Math.ceilDiv(%d, %d) = %s; expected %s%n", x, y, result, expected);
}
Object strict_result = doStrictCeilDiv(x, y);
if (!resultEquals(strict_result, expected)) {
fail("FAIL: long StrictMath.ceilDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
}
}
/**
* Test CeilMod of long arguments against expected value.
* The expected value is usually a Long but in some cases is
* an ArithmeticException.
*
* @param x dividend
* @param y modulus
* @param expected expected value
*/
static void testLongCeilMod(long x, long y, Object expected) {
Object result = doCeilMod(x, y);
if (!resultEquals(result, expected)) {
fail("FAIL: long Math.ceilMod(%d, %d) = %s; expected %s%n", x, y, result, expected);
}
Object strict_result = doStrictCeilMod(x, y);
if (!resultEquals(strict_result, expected)) {
fail("FAIL: long StrictMath.ceilMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
}
try {
// Verify the result against BigDecimal rounding mode.
BigDecimal xD = new BigDecimal(x);
BigDecimal yD = new BigDecimal(y);
BigDecimal resultD = xD.divide(yD, RoundingMode.CEILING);
resultD = resultD.multiply(yD);
resultD = xD.subtract(resultD);
long fr = resultD.longValue();
if (!result.equals(fr)) {
fail("FAIL: Long.ceilMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr);
}
} catch (ArithmeticException ae) {
if (y != 0) {
fail("FAIL: long Math.ceilMod(%d, %d); unexpected ArithmeticException from bigdecimal");
}
}
}
/**
* Test the ceilDiv and ceilMod methods for mixed long and int.
*/
static void testLongIntCeilDivMod() {
testLongIntCeilDivMod(4L, 0, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException
testLongIntCeilDivMod(4L, 3, 2L, -2);
testLongIntCeilDivMod(3L, 3, 1L, 0);
testLongIntCeilDivMod(2L, 3, 1L, -1);
testLongIntCeilDivMod(1L, 3, 1L, -2);
testLongIntCeilDivMod(0L, 3, 0L, 0);
testLongIntCeilDivMod(4L, -3, -1L, 1);
testLongIntCeilDivMod(3L, -3, -1L, 0);
testLongIntCeilDivMod(2L, -3, 0L, 2);
testLongIntCeilDivMod(1L, -3, 0L, 1);
testLongIntCeilDivMod(0L, -3, 0L, 0);
testLongIntCeilDivMod(-1L, 3, 0L, -1);
testLongIntCeilDivMod(-2L, 3, 0L, -2);
testLongIntCeilDivMod(-3L, 3, -1L, 0);
testLongIntCeilDivMod(-4L, 3, -1L, -1);
testLongIntCeilDivMod(-1L, -3, 1L, 2);
testLongIntCeilDivMod(-2L, -3, 1L, 1);
testLongIntCeilDivMod(-3L, -3, 1L, 0);
testLongIntCeilDivMod(-4L, -3, 2L, 2);
testLongIntCeilDivMod(Long.MAX_VALUE, 1, Long.MAX_VALUE, 0);
testLongIntCeilDivMod(Long.MAX_VALUE, -1, -Long.MAX_VALUE, 0);
testLongIntCeilDivMod(Long.MAX_VALUE, 3, Long.MAX_VALUE / 3L + 1, -2);
testLongIntCeilDivMod(Long.MAX_VALUE - 1L, 3, (Long.MAX_VALUE - 1L) / 3L, 0);
testLongIntCeilDivMod(Long.MIN_VALUE, 3, Long.MIN_VALUE / 3L, -2);
testLongIntCeilDivMod(Long.MIN_VALUE + 1L, 3, Long.MIN_VALUE / 3L, -1);
testLongIntCeilDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0);
testLongIntCeilDivMod(Long.MAX_VALUE, Integer.MAX_VALUE, 4_294_967_299L, -2_147_483_646);
testLongIntCeilDivMod(Long.MAX_VALUE, Integer.MIN_VALUE, -4_294_967_295L, 2_147_483_647);
testLongIntCeilDivMod(Long.MIN_VALUE, Integer.MIN_VALUE, 4_294_967_296L, 0);
testLongIntCeilDivMod(Long.MIN_VALUE, Integer.MAX_VALUE, -4_294_967_298L, -2);
// Special case of integer overflow
testLongIntCeilDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0);
}
/**
* Test the integer ceilDiv and ceilMod methods.
* Math and StrictMath are tested and the same results are expected for both.
*/
static void testLongIntCeilDivMod(long x, int y, Object divExpected, Object modExpected) {
testLongIntCeilDiv(x, y, divExpected);
testLongIntCeilMod(x, y, modExpected);
}
/**
* Test CeilDiv with long arguments against expected value.
* The expected value is usually a Long but in some cases is
* an ArithmeticException.
*
* @param x dividend
* @param y modulus
* @param expected expected value,
*/
static void testLongIntCeilDiv(long x, int y, Object expected) {
Object result = doCeilDiv(x, y);
if (!resultEquals(result, expected)) {
fail("FAIL: long Math.ceilDiv(%d, %d) = %s; expected %s%n", x, y, result, expected);
}
Object strict_result = doStrictCeilDiv(x, y);
if (!resultEquals(strict_result, expected)) {
fail("FAIL: long StrictMath.ceilDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
}
}
/**
* Test CeilMod of long arguments against expected value.
* The expected value is usually a Long but in some cases is
* an ArithmeticException.
*
* @param x dividend
* @param y modulus
* @param expected expected value
*/
static void testLongIntCeilMod(long x, int y, Object expected) {
Object result = doCeilMod(x, y);
if (!resultEquals(result, expected)) {
fail("FAIL: int Math.ceilMod(%d, %d) = %s; expected %s%n", x, y, result, expected);
}
Object strict_result = doStrictCeilMod(x, y);
if (!resultEquals(strict_result, expected)) {
fail("FAIL: int StrictMath.ceilMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
}
try {
// Verify the result against BigDecimal rounding mode.
BigDecimal xD = new BigDecimal(x);
BigDecimal yD = new BigDecimal(y);
BigDecimal resultD = xD.divide(yD, RoundingMode.CEILING);
resultD = resultD.multiply(yD);
resultD = xD.subtract(resultD);
int fr = resultD.intValue();
if (!result.equals(fr)) {
fail("FAIL: Long.ceilMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr);
}
} catch (ArithmeticException ae) {
if (y != 0) {
fail("FAIL: long Math.ceilMod(%d, %d); unexpected ArithmeticException from bigdecimal");
}
}
}
/**
* Invoke ceilDiv and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doCeilDiv(int x, int y) {
try {
return Math.ceilDiv(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilDiv and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doCeilDiv(long x, int y) {
try {
return Math.ceilDiv(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilDiv and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doCeilDiv(long x, long y) {
try {
return Math.ceilDiv(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doCeilMod(int x, int y) {
try {
return Math.ceilMod(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doCeilMod(long x, int y) {
try {
return Math.ceilMod(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doCeilMod(long x, long y) {
try {
return Math.ceilMod(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilDiv and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doStrictCeilDiv(int x, int y) {
try {
return StrictMath.ceilDiv(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilDiv and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doStrictCeilDiv(long x, int y) {
try {
return StrictMath.ceilDiv(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilDiv and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doStrictCeilDiv(long x, long y) {
try {
return StrictMath.ceilDiv(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doStrictCeilMod(int x, int y) {
try {
return StrictMath.ceilMod(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doStrictCeilMod(long x, int y) {
try {
return StrictMath.ceilMod(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Invoke ceilMod and return the result or any exception.
* @param x the x value
* @param y the y value
* @return the result Integer or an exception.
*/
static Object doStrictCeilMod(long x, long y) {
try {
return StrictMath.ceilMod(x, y);
} catch (ArithmeticException ae) {
return ae;
}
}
/**
* Returns a boolean by comparing the result and the expected value.
* The equals method is not defined for ArithmeticException but it is

View File

@ -25,7 +25,7 @@ import java.math.BigInteger;
/**
* @test Test for Math.*Exact integer and long methods.
* @bug 6708398 8075806
* @bug 6708398 8075806 8271225 8271602
* @summary Basic tests for Math exact arithmetic operations.
*
* @author Roger Riggs
@ -57,8 +57,8 @@ public class ExactArithTests {
/**
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
* floorDivExact, incrementExact, decrementExact, negateExact methods with
* {@code int} arguments.
* floorDivExact, ceilDivExact, incrementExact, decrementExact, negateExact
* methods with {@code int} arguments.
*/
static void testIntegerExact() {
testIntegerExact(0, 0);
@ -194,6 +194,34 @@ public class ExactArithTests {
}
}
exceptionExpected = false;
try {
// Test ceilDivExact
int q = 0;
try {
q = Math.ceilDiv(x, y);
} catch (ArithmeticException e) {
exceptionExpected = true;
}
if (!exceptionExpected && x == Integer.MIN_VALUE && y == -1) {
exceptionExpected = true;
}
int z = Math.ceilDivExact(x, y);
if (exceptionExpected) {
fail("FAIL: int Math.ceilDivExact(" + x + " / " + y + ")" +
"; expected ArithmeticException not thrown");
}
if (z != q) {
fail("FAIL: int Math.ceilDivExact(" + x + " / " + y + ") = " +
z + "; expected: " + q);
}
} catch (ArithmeticException ex) {
if (!exceptionExpected) {
fail("FAIL: int Math.ceilDivExact(" + x + " / " + y + ")" +
"; Unexpected exception: " + ex);
}
}
try {
// Test incrementExact
int inc = Math.incrementExact(x);
@ -245,7 +273,7 @@ public class ExactArithTests {
/**
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
* floorDivExact, incrementExact, decrementExact, negateExact, toIntExact
* floorDivExact, ceilDivExact, incrementExact, decrementExact, negateExact, toIntExact
* methods with {@code long} arguments.
*/
static void testLongExact() {
@ -380,6 +408,34 @@ public class ExactArithTests {
}
}
exceptionExpected = false;
try {
// Test ceilDivExact
long q = 0;
try {
q = Math.ceilDiv(x, y);
} catch (ArithmeticException e) {
exceptionExpected = true;
}
if (!exceptionExpected && x == Long.MIN_VALUE && y == -1) {
exceptionExpected = true;
}
long z = Math.ceilDivExact(x, y);
if (exceptionExpected) {
fail("FAIL: long Math.ceilDivExact(" + x + " / " + y + ")" +
"; expected ArithmeticException not thrown");
}
if (z != q) {
fail("FAIL: long Math.ceilDivExact(" + x + " / " + y + ") = " +
z + "; expected: " + q);
}
} catch (ArithmeticException ex) {
if (!exceptionExpected) {
fail("FAIL: long Math.ceilDivExact(" + x + " / " + y + ")" +
"; Unexpected exception: " + ex);
}
}
try {
// Test incrementExact
resultBig = xBig.add(BigInteger.ONE);