mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8075806: divideExact is missing in java.lang.Math
Reviewed-by: darcy
This commit is contained in:
parent
efa63dc1c6
commit
0b12e7c82c
3 changed files with 167 additions and 20 deletions
|
@ -91,13 +91,8 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
||||||
* will not overflow the range of values of the computation.
|
* will not overflow the range of values of the computation.
|
||||||
* The best practice is to choose the primitive type and algorithm to avoid
|
* 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. In cases where the size is {@code int} or {@code long} and
|
||||||
* overflow errors need to be detected, the methods {@code addExact},
|
* overflow errors need to be detected, the methods whose names end with
|
||||||
* {@code subtractExact}, {@code multiplyExact}, {@code toIntExact},
|
* {@code Exact} throw an {@code ArithmeticException} when the results overflow.
|
||||||
* {@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.
|
|
||||||
*
|
*
|
||||||
* <h2><a id=Ieee754RecommendedOps>IEEE 754 Recommended
|
* <h2><a id=Ieee754RecommendedOps>IEEE 754 Recommended
|
||||||
* Operations</a></h2>
|
* Operations</a></h2>
|
||||||
|
@ -1007,6 +1002,60 @@ public final class Math {
|
||||||
return r;
|
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
|
* Returns the argument incremented by one, throwing an exception if the
|
||||||
* result overflows an {@code int}.
|
* 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.
|
* will not overflow the range of values of the computation.
|
||||||
* The best practice is to choose the primitive type and algorithm to avoid
|
* 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. In cases where the size is {@code int} or {@code long} and
|
||||||
* overflow errors need to be detected, the methods {@code addExact},
|
* overflow errors need to be detected, the methods whose names end with
|
||||||
* {@code subtractExact}, {@code multiplyExact}, {@code toIntExact},
|
* {@code Exact} throw an {@code ArithmeticException} when the results overflow.
|
||||||
* {@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.
|
|
||||||
*
|
*
|
||||||
* <h2><a id=Ieee754RecommendedOps>IEEE 754 Recommended
|
* <h2><a id=Ieee754RecommendedOps>IEEE 754 Recommended
|
||||||
* Operations</a></h2>
|
* Operations</a></h2>
|
||||||
|
@ -858,6 +853,54 @@ public final class StrictMath {
|
||||||
return Math.multiplyExact(x, y);
|
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,
|
* 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}.
|
||||||
|
|
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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.
|
* @test Test for Math.*Exact integer and long methods.
|
||||||
* @bug 6708398
|
* @bug 6708398 8075806
|
||||||
* @summary Basic tests for Math exact arithmetic operations.
|
* @summary Basic tests for Math exact arithmetic operations.
|
||||||
*
|
*
|
||||||
* @author Roger Riggs
|
* @author Roger Riggs
|
||||||
|
@ -56,8 +56,9 @@ public class ExactArithTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Math.addExact, multiplyExact, subtractExact, incrementExact,
|
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
|
||||||
* decrementExact, negateExact methods with {@code int} arguments.
|
* incrementExact, decrementExact, negateExact methods with
|
||||||
|
* {@code int} arguments.
|
||||||
*/
|
*/
|
||||||
static void testIntegerExact() {
|
static void testIntegerExact() {
|
||||||
testIntegerExact(0, 0);
|
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 {
|
try {
|
||||||
// Test incrementExact
|
// Test incrementExact
|
||||||
int inc = Math.incrementExact(x);
|
int inc = Math.incrementExact(x);
|
||||||
|
@ -182,8 +216,9 @@ public class ExactArithTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Math.addExact, multiplyExact, subtractExact, incrementExact,
|
* Test Math.addExact, multiplyExact, divideExact, subtractExact,
|
||||||
* decrementExact, negateExact, toIntExact methods with {@code long} arguments.
|
* incrementExact, decrementExact, negateExact, toIntExact methods
|
||||||
|
* with {@code long} arguments.
|
||||||
*/
|
*/
|
||||||
static void testLongExact() {
|
static void testLongExact() {
|
||||||
testLongExactTwice(0, 0);
|
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 {
|
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