clementbera | 0bdd90f | 2019-07-06 11:15:23 +0200 | [diff] [blame] | 1 | // Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file |
| 2 | // for details. All rights reserved. Use of this source code is governed by a |
| 3 | // BSD-style license that can be found in the LICENSE file. |
| 4 | |
| 5 | package backport; |
| 6 | |
Jake Wharton | 9402c90 | 2019-12-12 09:06:14 -0500 | [diff] [blame] | 7 | import java.math.BigInteger; |
| 8 | |
clementbera | 0bdd90f | 2019-07-06 11:15:23 +0200 | [diff] [blame] | 9 | public class MathBackportJava9Main { |
| 10 | |
| 11 | public static void main(String[] args) { |
| 12 | testMultiplyExactLongInt(); |
Jake Wharton | 971ee70 | 2019-12-11 21:19:30 -0500 | [diff] [blame] | 13 | testMultiplyFull(); |
Jake Wharton | 9402c90 | 2019-12-12 09:06:14 -0500 | [diff] [blame] | 14 | testMultiplyHigh(); |
clementbera | 0bdd90f | 2019-07-06 11:15:23 +0200 | [diff] [blame] | 15 | testFloorDivLongInt(); |
| 16 | testFloorModLongInt(); |
| 17 | } |
| 18 | |
| 19 | public static void testMultiplyExactLongInt() { |
| 20 | assertEquals(8L, Math.multiplyExact(2L, 4)); |
| 21 | assertEquals(Long.MAX_VALUE, Math.multiplyExact(Long.MAX_VALUE, 1)); |
| 22 | assertEquals(Long.MIN_VALUE, Math.multiplyExact(Long.MIN_VALUE / 2L, 2)); |
| 23 | try { |
| 24 | throw new AssertionError(Math.multiplyExact(Long.MAX_VALUE, 2)); |
| 25 | } catch (ArithmeticException expected) { |
| 26 | } |
| 27 | try { |
| 28 | throw new AssertionError(Math.multiplyExact(Long.MIN_VALUE, 2)); |
| 29 | } catch (ArithmeticException expected) { |
| 30 | } |
| 31 | } |
| 32 | |
Jake Wharton | 971ee70 | 2019-12-11 21:19:30 -0500 | [diff] [blame] | 33 | public static void testMultiplyFull() { |
| 34 | assertEquals(8L, Math.multiplyFull(2, 4)); |
| 35 | assertEquals(4611686014132420609L, |
| 36 | Math.multiplyFull(Integer.MAX_VALUE, Integer.MAX_VALUE)); |
| 37 | assertEquals(-4611686016279904256L, |
| 38 | Math.multiplyFull(Integer.MAX_VALUE, Integer.MIN_VALUE)); |
| 39 | assertEquals(4611686018427387904L, |
| 40 | Math.multiplyFull(Integer.MIN_VALUE, Integer.MIN_VALUE)); |
| 41 | } |
| 42 | |
Jake Wharton | 9402c90 | 2019-12-12 09:06:14 -0500 | [diff] [blame] | 43 | public static void testMultiplyHigh() { |
| 44 | long[] interestingValues = { |
| 45 | Long.MIN_VALUE, Long.MAX_VALUE, |
| 46 | Integer.MIN_VALUE, Integer.MAX_VALUE, |
| 47 | Short.MIN_VALUE, Short.MAX_VALUE, |
| 48 | Byte.MIN_VALUE, Byte.MAX_VALUE, |
| 49 | 0L, |
| 50 | -1L, 1L, |
| 51 | -42L, 42L |
| 52 | }; |
| 53 | for (long x : interestingValues) { |
| 54 | for (long y : interestingValues) { |
| 55 | long expected = BigInteger.valueOf(x) |
| 56 | .multiply(BigInteger.valueOf(y)) |
| 57 | .shiftRight(64) |
| 58 | .longValue(); |
| 59 | assertEquals(expected, Math.multiplyHigh(x, y)); |
| 60 | } |
| 61 | } |
| 62 | } |
| 63 | |
clementbera | 0bdd90f | 2019-07-06 11:15:23 +0200 | [diff] [blame] | 64 | public static void testFloorDivLongInt() { |
| 65 | assertEquals(1L, Math.floorDiv(4L, 4)); |
| 66 | assertEquals(1L, Math.floorDiv(-4L, -4)); |
| 67 | assertEquals(-1L, Math.floorDiv(-4L, 4)); |
| 68 | assertEquals(-1L, Math.floorDiv(4L, -4)); |
| 69 | |
| 70 | assertEquals(1L, Math.floorDiv(4L, 3)); |
| 71 | assertEquals(1L, Math.floorDiv(-4L, -3)); |
| 72 | assertEquals(-2L, Math.floorDiv(-4L, 3)); |
| 73 | assertEquals(-2L, Math.floorDiv(4L, -3)); |
| 74 | |
| 75 | // Spec edge case: result is actually MAX_VALUE+1 which becomes MIN_VALUE. |
| 76 | assertEquals(Long.MIN_VALUE, Math.floorDiv(Long.MIN_VALUE, -1)); |
| 77 | } |
| 78 | |
| 79 | public static void testFloorModLongInt() { |
| 80 | assertEquals(0, Math.floorMod(4L, 4)); |
| 81 | assertEquals(0, Math.floorMod(-4L, -4)); |
| 82 | assertEquals(0, Math.floorMod(-4L, 4)); |
| 83 | assertEquals(0, Math.floorMod(4L, -4)); |
| 84 | |
| 85 | assertEquals(1, Math.floorMod(4L, 3)); |
| 86 | assertEquals(-1, Math.floorMod(-4L, -3)); |
| 87 | assertEquals(2, Math.floorMod(-4L, 3)); |
| 88 | assertEquals(-2, Math.floorMod(4L, -3)); |
| 89 | } |
| 90 | |
| 91 | private static void assertEquals(int expected, int actual) { |
| 92 | if (expected != actual) { |
| 93 | throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>'); |
| 94 | } |
| 95 | } |
| 96 | |
| 97 | private static void assertEquals(long expected, long actual) { |
| 98 | if (expected != actual) { |
| 99 | throw new AssertionError("Expected <" + expected + "> but was <" + actual + '>'); |
| 100 | } |
| 101 | } |
| 102 | } |