8241374: add Math.absExact
Reviewed-by: smarks, chegar, bpb
This commit is contained in:
parent
b7439a8ae3
commit
916f00acc1
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1994, 2020, 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
|
||||
@ -1355,37 +1355,93 @@ public final class Math {
|
||||
* If the argument is not negative, the argument is returned.
|
||||
* If the argument is negative, the negation of the argument is returned.
|
||||
*
|
||||
* <p>Note that if the argument is equal to the value of
|
||||
* {@link Integer#MIN_VALUE}, the most negative representable
|
||||
* {@code int} value, the result is that same value, which is
|
||||
* negative.
|
||||
* <p>Note that if the argument is equal to the value of {@link
|
||||
* Integer#MIN_VALUE}, the most negative representable {@code int}
|
||||
* value, the result is that same value, which is negative. In
|
||||
* contrast, the {@link Math#absExact(int)} method throws an
|
||||
* {@code ArithmeticException} for this value.
|
||||
*
|
||||
* @param a the argument whose absolute value is to be determined
|
||||
* @return the absolute value of the argument.
|
||||
* @see Math#absExact(int)
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
public static int abs(int a) {
|
||||
return (a < 0) ? -a : a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mathematical absolute value of an {@code int} value
|
||||
* if it is exactly representable as an {@code int}, throwing
|
||||
* {@code ArithmeticException} if the result overflows the
|
||||
* positive {@code int} range.
|
||||
*
|
||||
* <p>Since the range of two's complement integers is asymmetric
|
||||
* with one additional negative value (JLS {@jls 4.2.1}), the
|
||||
* mathematical absolute value of {@link Integer#MIN_VALUE}
|
||||
* overflows the positive {@code int} range, so an exception is
|
||||
* thrown for that argument.
|
||||
*
|
||||
* @param a the argument whose absolute value is to be determined
|
||||
* @return the absolute value of the argument, unless overflow occurs
|
||||
* @throws ArithmeticException if the argument is {@link Integer#MIN_VALUE}
|
||||
* @see Math#abs(int)
|
||||
* @since 15
|
||||
*/
|
||||
public static int absExact(int a) {
|
||||
if (a == Integer.MIN_VALUE)
|
||||
throw new ArithmeticException(
|
||||
"Overflow to represent absolute value of Integer.MIN_VALUE");
|
||||
else
|
||||
return abs(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a {@code long} value.
|
||||
* If the argument is not negative, the argument is returned.
|
||||
* If the argument is negative, the negation of the argument is returned.
|
||||
*
|
||||
* <p>Note that if the argument is equal to the value of
|
||||
* {@link Long#MIN_VALUE}, the most negative representable
|
||||
* {@code long} value, the result is that same value, which
|
||||
* is negative.
|
||||
* <p>Note that if the argument is equal to the value of {@link
|
||||
* Long#MIN_VALUE}, the most negative representable {@code long}
|
||||
* value, the result is that same value, which is negative. In
|
||||
* contrast, the {@link Math#absExact(long)} method throws an
|
||||
* {@code ArithmeticException} for this value.
|
||||
*
|
||||
* @param a the argument whose absolute value is to be determined
|
||||
* @return the absolute value of the argument.
|
||||
* @see Math#absExact(long)
|
||||
*/
|
||||
@HotSpotIntrinsicCandidate
|
||||
public static long abs(long a) {
|
||||
return (a < 0) ? -a : a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mathematical absolute value of an {@code long} value
|
||||
* if it is exactly representable as an {@code long}, throwing
|
||||
* {@code ArithmeticException} if the result overflows the
|
||||
* positive {@code long} range.
|
||||
*
|
||||
* <p>Since the range of two's complement integers is asymmetric
|
||||
* with one additional negative value (JLS {@jls 4.2.1}), the
|
||||
* mathematical absolute value of {@link Long#MIN_VALUE} overflows
|
||||
* the positive {@code long} range, so an exception is thrown for
|
||||
* that argument.
|
||||
*
|
||||
* @param a the argument whose absolute value is to be determined
|
||||
* @return the absolute value of the argument, unless overflow occurs
|
||||
* @throws ArithmeticException if the argument is {@link Long#MIN_VALUE}
|
||||
* @see Math#abs(long)
|
||||
* @since 15
|
||||
*/
|
||||
public static long absExact(long a) {
|
||||
if (a == Long.MIN_VALUE)
|
||||
throw new ArithmeticException(
|
||||
"Overflow to represent absolute value of Long.MIN_VALUE");
|
||||
else
|
||||
return abs(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a {@code float} value.
|
||||
* If the argument is not negative, the argument is returned.
|
||||
|
@ -1124,35 +1124,85 @@ public final class StrictMath {
|
||||
* If the argument is not negative, the argument is returned.
|
||||
* If the argument is negative, the negation of the argument is returned.
|
||||
*
|
||||
* <p>Note that if the argument is equal to the value of
|
||||
* {@link Integer#MIN_VALUE}, the most negative representable
|
||||
* {@code int} value, the result is that same value, which is
|
||||
* negative.
|
||||
* <p>Note that if the argument is equal to the value of {@link
|
||||
* Integer#MIN_VALUE}, the most negative representable {@code int}
|
||||
* value, the result is that same value, which is negative. In
|
||||
* contrast, the {@link StrictMath#absExact(int)} method throws an
|
||||
* {@code ArithmeticException} for this value.
|
||||
*
|
||||
* @param a the argument whose absolute value is to be determined.
|
||||
* @return the absolute value of the argument.
|
||||
* @see Math#absExact(int)
|
||||
*/
|
||||
public static int abs(int a) {
|
||||
return Math.abs(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mathematical absolute value of an {@code int} value
|
||||
* if it is exactly representable as an {@code int}, throwing
|
||||
* {@code ArithmeticException} if the result overflows the
|
||||
* positive {@code int} range.
|
||||
*
|
||||
* <p>Since the range of two's complement integers is asymmetric
|
||||
* with one additional negative value (JLS {@jls 4.2.1}), the
|
||||
* mathematical absolute value of {@link Integer#MIN_VALUE}
|
||||
* overflows the positive {@code int} range, so an exception is
|
||||
* thrown for that argument.
|
||||
*
|
||||
* @param a the argument whose absolute value is to be determined
|
||||
* @return the absolute value of the argument, unless overflow occurs
|
||||
* @throws ArithmeticException if the argument is {@link Integer#MIN_VALUE}
|
||||
* @see Math#abs(int)
|
||||
* @see Math#absExact(int)
|
||||
* @since 15
|
||||
*/
|
||||
public static int absExact(int a) {
|
||||
return Math.absExact(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a {@code long} value.
|
||||
* If the argument is not negative, the argument is returned.
|
||||
* If the argument is negative, the negation of the argument is returned.
|
||||
*
|
||||
* <p>Note that if the argument is equal to the value of
|
||||
* {@link Long#MIN_VALUE}, the most negative representable
|
||||
* {@code long} value, the result is that same value, which
|
||||
* is negative.
|
||||
* <p>Note that if the argument is equal to the value of {@link
|
||||
* Long#MIN_VALUE}, the most negative representable {@code long}
|
||||
* value, the result is that same value, which is negative. In
|
||||
* contrast, the {@link StrictMath#absExact(long)} method throws
|
||||
* an {@code ArithmeticException} for this value.
|
||||
*
|
||||
* @param a the argument whose absolute value is to be determined.
|
||||
* @return the absolute value of the argument.
|
||||
* @see Math#absExact(long)
|
||||
*/
|
||||
public static long abs(long a) {
|
||||
return Math.abs(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mathematical absolute value of an {@code long} value
|
||||
* if it is exactly representable as an {@code long}, throwing
|
||||
* {@code ArithmeticException} if the result overflows the
|
||||
* positive {@code long} range.
|
||||
*
|
||||
* <p>Since the range of two's complement integers is asymmetric
|
||||
* with one additional negative value (JLS {@jls 4.2.1}), the
|
||||
* mathematical absolute value of {@link Long#MIN_VALUE} overflows
|
||||
* the positive {@code long} range, so an exception is thrown for
|
||||
* that argument.
|
||||
*
|
||||
* @param a the argument whose absolute value is to be determined
|
||||
* @return the absolute value of the argument, unless overflow occurs
|
||||
* @throws ArithmeticException if the argument is {@link Long#MIN_VALUE}
|
||||
* @see Math#abs(long)
|
||||
* @see Math#absExact(long)
|
||||
* @since 15
|
||||
*/
|
||||
public static long absExact(long a) {
|
||||
return Math.absExact(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a {@code float} value.
|
||||
* If the argument is not negative, the argument is returned.
|
||||
|
146
test/jdk/java/lang/Math/AbsTests.java
Normal file
146
test/jdk/java/lang/Math/AbsTests.java
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.util.function.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8241374
|
||||
* @summary Test abs and absExact for Math and StrictMath
|
||||
*/
|
||||
public class AbsTests {
|
||||
private static int errors = 0;
|
||||
|
||||
public static void main(String... args) {
|
||||
errors += testInRangeIntAbs();
|
||||
errors += testIntMinValue();
|
||||
errors += testInRangeLongAbs();
|
||||
errors += testLongMinValue();
|
||||
|
||||
if (errors > 0) {
|
||||
throw new RuntimeException(errors + " errors found testing abs.");
|
||||
}
|
||||
}
|
||||
|
||||
private static int testInRangeIntAbs() {
|
||||
int errors = 0;
|
||||
int[][] testCases = {
|
||||
// Argument to abs, expected result
|
||||
{+0, 0},
|
||||
{+1, 1},
|
||||
{-1, 1},
|
||||
{-2, 2},
|
||||
{+2, 2},
|
||||
{-Integer.MAX_VALUE, Integer.MAX_VALUE},
|
||||
{+Integer.MAX_VALUE, Integer.MAX_VALUE}
|
||||
};
|
||||
|
||||
for(var testCase : testCases) {
|
||||
errors += testIntAbs(Math::abs, testCase[0], testCase[1]);
|
||||
errors += testIntAbs(Math::absExact, testCase[0], testCase[1]);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testIntMinValue() {
|
||||
int errors = 0;
|
||||
// Strange but true
|
||||
errors += testIntAbs(Math::abs, Integer.MIN_VALUE, Integer.MIN_VALUE);
|
||||
|
||||
// Test exceptional behavior for absExact
|
||||
try {
|
||||
int result = Math.absExact(Integer.MIN_VALUE);
|
||||
System.err.printf("Bad return value %d from Math.absExact(MIN_VALUE)%n",
|
||||
result);
|
||||
errors++;
|
||||
} catch (ArithmeticException ae) {
|
||||
; // Expected
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testIntAbs(IntUnaryOperator absFunc,
|
||||
int argument, int expected) {
|
||||
int result = absFunc.applyAsInt(argument);
|
||||
if (result != expected) {
|
||||
System.err.printf("Unexpected int abs result %d for argument %d%n",
|
||||
result, argument);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
private static long testInRangeLongAbs() {
|
||||
int errors = 0;
|
||||
long[][] testCases = {
|
||||
// Argument to abs, expected result
|
||||
{+0L, 0L},
|
||||
{+1L, 1L},
|
||||
{-1L, 1L},
|
||||
{-2L, 2L},
|
||||
{+2L, 2L},
|
||||
{-Integer.MAX_VALUE, Integer.MAX_VALUE},
|
||||
{+Integer.MAX_VALUE, Integer.MAX_VALUE},
|
||||
{ Integer.MIN_VALUE, -((long)Integer.MIN_VALUE)},
|
||||
{-Long.MAX_VALUE, Long.MAX_VALUE},
|
||||
};
|
||||
|
||||
for(var testCase : testCases) {
|
||||
errors += testLongAbs(Math::abs, testCase[0], testCase[1]);
|
||||
errors += testLongAbs(Math::absExact, testCase[0], testCase[1]);
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testLongMinValue() {
|
||||
int errors = 0;
|
||||
// Strange but true
|
||||
errors += testLongAbs(Math::abs, Long.MIN_VALUE, Long.MIN_VALUE);
|
||||
|
||||
// Test exceptional behavior for absExact
|
||||
try {
|
||||
long result = Math.absExact(Long.MIN_VALUE);
|
||||
System.err.printf("Bad return value %d from Math.absExact(MIN_VALUE)%n",
|
||||
result);
|
||||
errors++;
|
||||
} catch (ArithmeticException ae) {
|
||||
; // Expected
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
private static int testLongAbs(LongUnaryOperator absFunc,
|
||||
long argument, long expected) {
|
||||
long result = absFunc.applyAsLong(argument);
|
||||
if (result != expected) {
|
||||
System.err.printf("Unexpected long abs result %d for argument %d%n",
|
||||
result, argument);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user