11/*
2- * Copyright (c) 2016, 2017 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2016, 2021 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
2626 * @library /test/lib
2727 * @build jdk.test.lib.RandomFactory
2828 * @run main MultiplicationTests
29- * @bug 5100935
29+ * @bug 5100935 8188044
3030 * @summary Tests for multiplication methods (use -Dseed=X to set PRNG seed)
3131 * @key randomness
3232 */
3333
3434import java .math .BigInteger ;
35+ import java .util .function .BiFunction ;
3536import jdk .test .lib .RandomFactory ;
3637
3738public class MultiplicationTests {
@@ -49,10 +50,25 @@ private static long multiplyHighBigInt(long x, long y) {
4950 .shiftRight (64 ).longValue ();
5051 }
5152
52- // Check Math.multiplyHigh(x,y) against multiplyHighBigInt(x,y)
53- private static boolean check (long x , long y ) {
54- long p1 = multiplyHighBigInt (x , y );
55- long p2 = Math .multiplyHigh (x , y );
53+ // Calculate high 64 bits of unsigned 128 product using signed multiply
54+ private static long unsignedMultiplyHigh (long x , long y ) {
55+ long x0 = x & 0xffffffffL ;
56+ long x1 = x >>> 32 ;
57+ long y0 = y & 0xffffffffL ;
58+ long y1 = y >>> 32 ;
59+
60+ long t = x1 * y0 + ((x0 * y0 ) >>> 32 );
61+ long z0 = x0 * y1 + (t & 0xffffffffL );
62+ long z1 = t >>> 32 ;
63+
64+ return x1 * y1 + z1 + (z0 >>> 32 );
65+ }
66+
67+ // Compare results of two functions for a pair of values
68+ private static boolean check (BiFunction <Long ,Long ,Long > reference ,
69+ BiFunction <Long ,Long ,Long > multiply , long x , long y ) {
70+ long p1 = reference .apply (x , y );
71+ long p2 = multiply .apply (x , y );
5672 if (p1 != p2 ) {
5773 System .err .printf ("Error - x:%d y:%d p1:%d p2:%d\n " , x , y , p1 , p2 );
5874 return false ;
@@ -61,7 +77,19 @@ private static boolean check(long x, long y) {
6177 }
6278 }
6379
64- private static int testMultiplyHigh () {
80+ // Check Math.multiplyHigh(x,y) against multiplyHighBigInt(x,y)
81+ private static boolean checkSigned (long x , long y ) {
82+ return check ((a ,b ) -> multiplyHighBigInt (a ,b ),
83+ (a ,b ) -> Math .multiplyHigh (a , b ), x , y );
84+ }
85+
86+ // Check Math.unsignedMultiplyHigh(x,y) against unsignedMultiplyHigh(x,y)
87+ private static boolean checkUnsigned (long x , long y ) {
88+ return check ((a ,b ) -> unsignedMultiplyHigh (a ,b ),
89+ (a ,b ) -> Math .unsignedMultiplyHigh (a , b ), x , y );
90+ }
91+
92+ private static int test (BiFunction <Long ,Long ,Boolean > chk ) {
6593 int failures = 0 ;
6694
6795 // check some boundary cases
@@ -84,23 +112,31 @@ private static int testMultiplyHigh() {
84112 };
85113
86114 for (long [] xy : v ) {
87- if (!check (xy [0 ], xy [1 ])) {
115+ if (!chk . apply (xy [0 ], xy [1 ])) {
88116 failures ++;
89117 }
90118 }
91119
92120 // check some random values
93121 for (int i = 0 ; i < COUNT ; i ++) {
94- if (!check (rnd .nextLong (), rnd .nextLong ())) {
122+ if (!chk . apply (rnd .nextLong (), rnd .nextLong ())) {
95123 failures ++;
96124 }
97125 }
98126
99127 return failures ;
100128 }
101129
130+ private static int testMultiplyHigh () {
131+ return test ((x ,y ) -> checkSigned (x ,y ));
132+ }
133+
134+ private static int testUnsignedMultiplyHigh () {
135+ return test ((x ,y ) -> checkUnsigned (x ,y ));
136+ }
137+
102138 public static void main (String argv []) {
103- int failures = testMultiplyHigh ();
139+ int failures = testMultiplyHigh () + testUnsignedMultiplyHigh () ;
104140
105141 if (failures > 0 ) {
106142 System .err .println ("Multiplication testing encountered "
0 commit comments