rev 12809 : 8023217: Additional floorDiv/floorMod/multiplyExact methods for java.lang.Math Summary: Add new methods with long, int signatures. Reviewed-by: XXX

@@ -1,7 +1,7 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2015, 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. Oracle designates this

@@ -92,11 +92,11 @@ * overflow. In cases where the size is {@code int} or {@code long} and * overflow errors need to be detected, the methods {@code addExact}, * {@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. * * @author unascribed * @author Joseph D. Darcy

@@ -858,11 +858,11 @@ */ @HotSpotIntrinsicCandidate 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"); } return r; }

@@ -879,11 +879,11 @@ */ @HotSpotIntrinsicCandidate 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"); } return r; }

@@ -906,10 +906,24 @@ } 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}. * * @param x the first value * @param y the second value

@@ -1062,16 +1076,16 @@ * Returns the largest (closest to positive infinity) * {@code int} value that is less than or equal to the algebraic quotient. * 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 * {@code floorDiv} and the {@code /} operator are the same. <br> * For example, {@code floorDiv(4, 3) == 1} and {@code (4 / 3) == 1}.</li>

@@ -1105,16 +1119,45 @@ * 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 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 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 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

@@ -1178,12 +1221,43 @@ * @throws ArithmeticException if the divisor {@code y} is zero * @see #floorDiv(int, int) * @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 or the + * result would overflow an {@code int} + * @see #floorDiv(long, int) + * @since 1.9 + */ + public static int floorMod(long x, int y) { + long r = x - floorDiv(x, y) * y; + int result = (int)r; + if (result != r) { + throw new ArithmeticException("integer overlow"); + } + return result; } /** * Returns the floor modulus of the {@code long} arguments. * <p>