8023217: Additional floorDiv/floorMod/multiplyExact methods for java.lang.Math
Add new methods with long, int signatures. Reviewed-by: darcy, scolebourne
This commit is contained in:
parent
1a2c01a37c
commit
3497da36a2
@ -95,7 +95,7 @@ import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
* {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
|
||||
* throw an {@code ArithmeticException} when the results overflow.
|
||||
* For other arithmetic operations such as divide, absolute value,
|
||||
* increment, decrement, and negation overflow occurs only with
|
||||
* increment by one, decrement by one, and negation, overflow occurs only with
|
||||
* a specific minimum or maximum value and should be checked against
|
||||
* the minimum or maximum as appropriate.
|
||||
*
|
||||
@ -861,7 +861,7 @@ public final class Math {
|
||||
public static int subtractExact(int x, int y) {
|
||||
int r = x - y;
|
||||
// HD 2-12 Overflow iff the arguments have different signs and
|
||||
// the sign of the result is different than the sign of x
|
||||
// the sign of the result is different from the sign of x
|
||||
if (((x ^ y) & (x ^ r)) < 0) {
|
||||
throw new ArithmeticException("integer overflow");
|
||||
}
|
||||
@ -882,7 +882,7 @@ public final class Math {
|
||||
public static long subtractExact(long x, long y) {
|
||||
long r = x - y;
|
||||
// HD 2-12 Overflow iff the arguments have different signs and
|
||||
// the sign of the result is different than the sign of x
|
||||
// the sign of the result is different from the sign of x
|
||||
if (((x ^ y) & (x ^ r)) < 0) {
|
||||
throw new ArithmeticException("long overflow");
|
||||
}
|
||||
@ -908,6 +908,20 @@ public final class Math {
|
||||
return (int)r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of the arguments, throwing an exception if the result
|
||||
* overflows a {@code long}.
|
||||
*
|
||||
* @param x the first value
|
||||
* @param y the second value
|
||||
* @return the result
|
||||
* @throws ArithmeticException if the result overflows a long
|
||||
* @since 1.9
|
||||
*/
|
||||
public static long multiplyExact(long x, int y) {
|
||||
return multiplyExact(x, (long)y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of the arguments,
|
||||
* throwing an exception if the result overflows a {@code long}.
|
||||
@ -1112,12 +1126,12 @@ public final class Math {
|
||||
* There is one special case, if the dividend is the
|
||||
* {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1},
|
||||
* then integer overflow occurs and
|
||||
* the result is equal to the {@code Integer.MIN_VALUE}.
|
||||
* 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
|
||||
* negative infinity (floor) rounding mode.
|
||||
* The floor rounding mode gives different results than truncation
|
||||
* The floor rounding mode gives different results from truncation
|
||||
* when the exact result is negative.
|
||||
* <ul>
|
||||
* <li>If the signs of the arguments are the same, the results of
|
||||
@ -1155,12 +1169,41 @@ public final class Math {
|
||||
* There is one special case, if the dividend is the
|
||||
* {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
|
||||
* then integer overflow occurs and
|
||||
* the result is equal to the {@code Long.MIN_VALUE}.
|
||||
* 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
|
||||
* negative infinity (floor) rounding mode.
|
||||
* The floor rounding mode gives different results than truncation
|
||||
* The floor rounding mode gives different results from truncation
|
||||
* when the exact result is negative.
|
||||
* <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
|
||||
* @see #floorMod(long, int)
|
||||
* @see #floor(double)
|
||||
* @since 1.9
|
||||
*/
|
||||
public static long floorDiv(long x, int y) {
|
||||
return floorDiv(x, (long)y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest (closest to positive infinity)
|
||||
* {@code long} value that is less than or equal to the algebraic quotient.
|
||||
* There is one special case, if the dividend is the
|
||||
* {@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
|
||||
* negative infinity (floor) rounding mode.
|
||||
* The floor rounding mode gives different results from truncation
|
||||
* when the exact result is negative.
|
||||
* <p>
|
||||
* For examples, see {@link #floorDiv(int, int)}.
|
||||
@ -1228,8 +1271,34 @@ public final class Math {
|
||||
* @since 1.8
|
||||
*/
|
||||
public static int floorMod(int x, int y) {
|
||||
int r = x - floorDiv(x, y) * y;
|
||||
return r;
|
||||
return x - floorDiv(x, y) * y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the floor modulus of the {@code long} and {@int} arguments.
|
||||
* <p>
|
||||
* The floor modulus is {@code x - (floorDiv(x, y) * y)},
|
||||
* has the same sign as the divisor {@code y}, and
|
||||
* is in the range of {@code -abs(y) < r < +abs(y)}.
|
||||
*
|
||||
* <p>
|
||||
* The relationship between {@code floorDiv} and {@code floorMod} is such that:
|
||||
* <ul>
|
||||
* <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
|
||||
* </ul>
|
||||
* <p>
|
||||
* For examples, see {@link #floorMod(int, int)}.
|
||||
*
|
||||
* @param x the dividend
|
||||
* @param y the divisor
|
||||
* @return the floor modulus {@code x - (floorDiv(x, y) * y)}
|
||||
* @throws ArithmeticException if the divisor {@code y} is zero
|
||||
* @see #floorDiv(long, int)
|
||||
* @since 1.9
|
||||
*/
|
||||
public static int floorMod(long x, int y) {
|
||||
// Result cannot overflow the range of int.
|
||||
return (int)(x - floorDiv(x, y) * y);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,7 +70,7 @@ import jdk.internal.HotSpotIntrinsicCandidate;
|
||||
* {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
|
||||
* throw an {@code ArithmeticException} when the results overflow.
|
||||
* For other arithmetic operations such as divide, absolute value,
|
||||
* increment, decrement, and negation overflow occurs only with
|
||||
* increment by one, decrement by one, and negation overflow occurs only with
|
||||
* a specific minimum or maximum value and should be checked against
|
||||
* the minimum or maximum as appropriate.
|
||||
*
|
||||
@ -802,6 +802,21 @@ public final class StrictMath {
|
||||
return Math.multiplyExact(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of the arguments, throwing an exception if the result
|
||||
* overflows a {@code long}.
|
||||
*
|
||||
* @param x the first value
|
||||
* @param y the second value
|
||||
* @return the result
|
||||
* @throws ArithmeticException if the result overflows a long
|
||||
* @see Math#multiplyExact(long,int)
|
||||
* @since 1.9
|
||||
*/
|
||||
public static long multiplyExact(long x, int y) {
|
||||
return Math.multiplyExact(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product of the arguments,
|
||||
* throwing an exception if the result overflows a {@code long}.
|
||||
@ -882,6 +897,30 @@ public final class StrictMath {
|
||||
return Math.floorDiv(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest (closest to positive infinity)
|
||||
* {@code long} value that is less than or equal to the algebraic quotient.
|
||||
* There is one special case, if the dividend is the
|
||||
* {@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#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
|
||||
* @see Math#floorDiv(long, int)
|
||||
* @see Math#floor(double)
|
||||
* @since 1.9
|
||||
*/
|
||||
public static long floorDiv(long x, int y) {
|
||||
return Math.floorDiv(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest (closest to positive infinity)
|
||||
* {@code long} value that is less than or equal to the algebraic quotient.
|
||||
@ -932,6 +971,35 @@ public final class StrictMath {
|
||||
public static int floorMod(int x, int y) {
|
||||
return Math.floorMod(x , y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the floor modulus of the {@code long} and {@int} arguments.
|
||||
* <p>
|
||||
* The floor modulus is {@code x - (floorDiv(x, y) * y)},
|
||||
* has the same sign as the divisor {@code y}, and
|
||||
* is in the range of {@code -abs(y) < r < +abs(y)}.
|
||||
*
|
||||
* <p>
|
||||
* The relationship between {@code floorDiv} and {@code floorMod} is such that:
|
||||
* <ul>
|
||||
* <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
|
||||
* </ul>
|
||||
* <p>
|
||||
* See {@link Math#floorMod(int, int) Math.floorMod} for examples and
|
||||
* a comparison to the {@code %} operator.
|
||||
*
|
||||
* @param x the dividend
|
||||
* @param y the divisor
|
||||
* @return the floor modulus {@code x - (floorDiv(x, y) * y)}
|
||||
* @throws ArithmeticException if the divisor {@code y} is zero
|
||||
* @see Math#floorMod(long, int)
|
||||
* @see StrictMath#floorDiv(long, int)
|
||||
* @since 1.9
|
||||
*/
|
||||
public static int floorMod(long x, int y) {
|
||||
return Math.floorMod(x , y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the floor modulus of the {@code long} arguments.
|
||||
* <p>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -342,7 +342,7 @@ public final class Instant
|
||||
*/
|
||||
public static Instant ofEpochMilli(long epochMilli) {
|
||||
long secs = Math.floorDiv(epochMilli, 1000);
|
||||
int mos = (int)Math.floorMod(epochMilli, 1000);
|
||||
int mos = Math.floorMod(epochMilli, 1000);
|
||||
return create(secs, mos * 1000_000);
|
||||
}
|
||||
|
||||
|
@ -826,7 +826,7 @@ public final class LocalDate
|
||||
* @return the day-of-week, not null
|
||||
*/
|
||||
public DayOfWeek getDayOfWeek() {
|
||||
int dow0 = (int)Math.floorMod(toEpochDay() + 3, 7);
|
||||
int dow0 = Math.floorMod(toEpochDay() + 3, 7);
|
||||
return DayOfWeek.of(dow0 + 1);
|
||||
}
|
||||
|
||||
@ -1329,7 +1329,7 @@ public final class LocalDate
|
||||
long monthCount = year * 12L + (month - 1);
|
||||
long calcMonths = monthCount + monthsToAdd; // safe overflow
|
||||
int newYear = YEAR.checkValidIntValue(Math.floorDiv(calcMonths, 12));
|
||||
int newMonth = (int)Math.floorMod(calcMonths, 12) + 1;
|
||||
int newMonth = Math.floorMod(calcMonths, 12) + 1;
|
||||
return resolvePreviousValid(newYear, newMonth, day);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -418,7 +418,7 @@ public final class LocalDateTime
|
||||
NANO_OF_SECOND.checkValidValue(nanoOfSecond);
|
||||
long localSecond = epochSecond + offset.getTotalSeconds(); // overflow caught later
|
||||
long localEpochDay = Math.floorDiv(localSecond, SECONDS_PER_DAY);
|
||||
int secsOfDay = (int)Math.floorMod(localSecond, SECONDS_PER_DAY);
|
||||
int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
|
||||
LocalDate date = LocalDate.ofEpochDay(localEpochDay);
|
||||
LocalTime time = LocalTime.ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + nanoOfSecond);
|
||||
return new LocalDateTime(date, time);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -361,7 +361,7 @@ public final class LocalTime
|
||||
Objects.requireNonNull(zone, "zone");
|
||||
ZoneOffset offset = zone.getRules().getOffset(instant);
|
||||
long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
|
||||
int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY);
|
||||
int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
|
||||
return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -258,7 +258,7 @@ public final class OffsetTime
|
||||
ZoneRules rules = zone.getRules();
|
||||
ZoneOffset offset = rules.getOffset(instant);
|
||||
long localSecond = instant.getEpochSecond() + offset.getTotalSeconds(); // overflow caught later
|
||||
int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY);
|
||||
int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
|
||||
LocalTime time = LocalTime.ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
|
||||
return new OffsetTime(time, offset);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -850,7 +850,7 @@ public final class YearMonth
|
||||
long monthCount = year * 12L + (month - 1);
|
||||
long calcMonths = monthCount + monthsToAdd; // safe overflow
|
||||
int newYear = YEAR.checkValidIntValue(Math.floorDiv(calcMonths, 12));
|
||||
int newMonth = (int)Math.floorMod(calcMonths, 12) + 1;
|
||||
int newMonth = Math.floorMod(calcMonths, 12) + 1;
|
||||
return with(newYear, newMonth);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -497,7 +497,7 @@ public final class HijrahDate
|
||||
* @return the day-of-week; computed from the epochday
|
||||
*/
|
||||
private int getDayOfWeek() {
|
||||
int dow0 = (int)Math.floorMod(toEpochDay() + 3, 7);
|
||||
int dow0 = Math.floorMod(toEpochDay() + 3, 7);
|
||||
return dow0 + 1;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -184,7 +184,7 @@ public class DivModTests {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the integer floorDiv and floorMod methods.
|
||||
* Test the long floorDiv and floorMod methods.
|
||||
* Math and StrictMath are tested and the same results are expected for both.
|
||||
*/
|
||||
static void testLongFloorDivMod(long x, long y, Object divExpected, Object modExpected) {
|
||||
@ -252,6 +252,110 @@ public class DivModTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the floorDiv and floorMod methods for mixed long and int.
|
||||
*/
|
||||
static void testLongIntFloorDivMod() {
|
||||
testLongIntFloorDivMod(4L, 0, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException
|
||||
testLongIntFloorDivMod(4L, 3, 1L, 1);
|
||||
testLongIntFloorDivMod(3L, 3, 1L, 0);
|
||||
testLongIntFloorDivMod(2L, 3, 0L, 2);
|
||||
testLongIntFloorDivMod(1L, 3, 0L, 1);
|
||||
testLongIntFloorDivMod(0L, 3, 0L, 0);
|
||||
testLongIntFloorDivMod(4L, -3, -2L, -2);
|
||||
testLongIntFloorDivMod(3L, -3, -1L, 0);
|
||||
testLongIntFloorDivMod(2L, -3, -1L, -1);
|
||||
testLongIntFloorDivMod(1L, -3, -1L, -2);
|
||||
testLongIntFloorDivMod(0L, -3, 0L, 0);
|
||||
testLongIntFloorDivMod(-1L, 3, -1L, 2);
|
||||
testLongIntFloorDivMod(-2L, 3, -1L, 1);
|
||||
testLongIntFloorDivMod(-3L, 3, -1L, 0);
|
||||
testLongIntFloorDivMod(-4L, 3, -2L, 2);
|
||||
testLongIntFloorDivMod(-1L, -3, 0L, -1);
|
||||
testLongIntFloorDivMod(-2L, -3, 0L, -2);
|
||||
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);
|
||||
// Special case of integer overflow
|
||||
testLongIntFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the integer floorDiv and floorMod methods.
|
||||
* Math and StrictMath are tested and the same results are expected for both.
|
||||
*/
|
||||
static void testLongIntFloorDivMod(long x, int y, Object divExpected, Object modExpected) {
|
||||
testLongIntFloorDiv(x, y, divExpected);
|
||||
testLongIntFloorMod(x, y, modExpected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test FloorDiv 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 testLongIntFloorDiv(long x, int y, Object expected) {
|
||||
Object result = doFloorDiv(x, y);
|
||||
if (!resultEquals(result, expected)) {
|
||||
fail("FAIL: long Math.floorDiv(%d, %d) = %s; expected %s%n", x, y, result, expected);
|
||||
}
|
||||
|
||||
Object strict_result = doStrictFloorDiv(x, y);
|
||||
if (!resultEquals(strict_result, expected)) {
|
||||
fail("FAIL: long StrictMath.floorDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test FloorMod 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 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
try {
|
||||
// Verify the result against BigDecimal rounding mode.
|
||||
BigDecimal xD = new BigDecimal(x);
|
||||
BigDecimal yD = new BigDecimal(y);
|
||||
BigDecimal resultD = xD.divide(yD, RoundingMode.FLOOR);
|
||||
resultD = resultD.multiply(yD);
|
||||
resultD = xD.subtract(resultD);
|
||||
long fr = resultD.longValue();
|
||||
if (!result.equals(fr)) {
|
||||
fail("FAIL: Long.floorMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr);
|
||||
|
||||
}
|
||||
} catch (ArithmeticException ae) {
|
||||
if (y != 0) {
|
||||
fail("FAIL: long Math.floorMod(%d, %d); unexpected ArithmeticException from bigdecimal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv and return the result or any exception.
|
||||
* @param x the x value
|
||||
@ -266,6 +370,20 @@ public class DivModTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv 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 doFloorDiv(long x, int y) {
|
||||
try {
|
||||
return Math.floorDiv(x, y);
|
||||
} catch (ArithmeticException ae) {
|
||||
return ae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv and return the result or any exception.
|
||||
* @param x the x value
|
||||
@ -294,6 +412,20 @@ public class DivModTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv 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 doFloorMod(long x, int y) {
|
||||
try {
|
||||
return Math.floorMod(x, y);
|
||||
} catch (ArithmeticException ae) {
|
||||
return ae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv and return the result or any exception.
|
||||
* @param x the x value
|
||||
@ -322,6 +454,20 @@ public class DivModTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv 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 doStrictFloorDiv(long x, int y) {
|
||||
try {
|
||||
return StrictMath.floorDiv(x, y);
|
||||
} catch (ArithmeticException ae) {
|
||||
return ae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv and return the result or any exception.
|
||||
* @param x the x value
|
||||
@ -350,6 +496,20 @@ public class DivModTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv 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 doStrictFloorMod(long x, int y) {
|
||||
try {
|
||||
return StrictMath.floorMod(x, y);
|
||||
} catch (ArithmeticException ae) {
|
||||
return ae;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke floorDiv and return the result or any exception.
|
||||
* @param x the x value
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2016, 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
|
||||
@ -43,6 +43,7 @@ public class ExactArithTests {
|
||||
public static void main(String[] args) {
|
||||
testIntegerExact();
|
||||
testLongExact();
|
||||
testLongIntExact();
|
||||
|
||||
if (errors > 0) {
|
||||
throw new RuntimeException(errors + " errors found in ExactArithTests.");
|
||||
@ -132,6 +133,7 @@ public class ExactArithTests {
|
||||
fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Test incrementExact
|
||||
int inc = Math.incrementExact(x);
|
||||
@ -345,4 +347,60 @@ public class ExactArithTests {
|
||||
static boolean inLongRange(BigInteger value) {
|
||||
return value.bitLength() <= 63;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Math.multiplyExact method with {@code long} and {@code int}
|
||||
* arguments.
|
||||
*/
|
||||
static void testLongIntExact() {
|
||||
testLongIntExact(0, 0);
|
||||
testLongIntExact(1, 1);
|
||||
testLongIntExact(1, -1);
|
||||
testLongIntExact(1000, 2000);
|
||||
|
||||
testLongIntExact(Long.MIN_VALUE, Integer.MIN_VALUE);
|
||||
testLongIntExact(Long.MAX_VALUE, Integer.MAX_VALUE);
|
||||
testLongIntExact(Long.MIN_VALUE, 1);
|
||||
testLongIntExact(Long.MAX_VALUE, 1);
|
||||
testLongIntExact(Long.MIN_VALUE, 2);
|
||||
testLongIntExact(Long.MAX_VALUE, 2);
|
||||
testLongIntExact(Long.MIN_VALUE, -1);
|
||||
testLongIntExact(Long.MAX_VALUE, -1);
|
||||
testLongIntExact(Long.MIN_VALUE, -2);
|
||||
testLongIntExact(Long.MAX_VALUE, -2);
|
||||
testLongIntExact(Long.MIN_VALUE/2, 2);
|
||||
testLongIntExact(Long.MAX_VALUE, 2);
|
||||
testLongIntExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
|
||||
testLongIntExact(Integer.MAX_VALUE, -Integer.MAX_VALUE);
|
||||
testLongIntExact((long)Integer.MAX_VALUE+1L, Integer.MAX_VALUE);
|
||||
testLongIntExact((long)Integer.MAX_VALUE+1L, -Integer.MAX_VALUE+1);
|
||||
testLongIntExact((long)Integer.MIN_VALUE-1L, Integer.MIN_VALUE);
|
||||
testLongIntExact((long)Integer.MIN_VALUE-1, Integer.MAX_VALUE);
|
||||
testLongIntExact(Integer.MIN_VALUE/2, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test long-int exact arithmetic by comparing with the same operations using BigInteger
|
||||
* and checking that the result is the same as the long truncation.
|
||||
* Errors are reported with {@link fail}.
|
||||
*
|
||||
* @param x first parameter
|
||||
* @param y second parameter
|
||||
*/
|
||||
static void testLongIntExact(long x, int y) {
|
||||
BigInteger resultBig = null;
|
||||
final BigInteger xBig = BigInteger.valueOf(x);
|
||||
final BigInteger yBig = BigInteger.valueOf(y);
|
||||
|
||||
try {
|
||||
// Test multiplyExact
|
||||
resultBig = xBig.multiply(yBig);
|
||||
long product = Math.multiplyExact(x, y);
|
||||
checkResult("long Math.multiplyExact", x, y, product, resultBig);
|
||||
} catch (ArithmeticException ex) {
|
||||
if (inLongRange(resultBig)) {
|
||||
fail("FAIL: long Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user