1 /*
   2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.util.function.*;
  25 
  26 /*
  27  * @test
  28  * @bug 8241374
  29  * @summary Test abs and absExact for Math and StrictMath
  30  */
  31 public class AbsTests {
  32     private static int errors = 0;
  33 
  34     public static void main(String... args) {
  35         errors += testInRangeIntAbs();
  36         errors += testIntMinValue();
  37         errors += testInRangeLongAbs();
  38         errors += testLongMinValue();
  39 
  40         if (errors > 0) {
  41             throw new RuntimeException(errors + " errors found testing abs.");
  42         }
  43     }
  44 
  45     private static int testInRangeIntAbs() {
  46         int errors = 0;
  47         int[][] testCases  = {
  48             // Argument to abs, expected result
  49             {+0, 0},
  50             {+1, 1},
  51             {-1, 1},
  52             {-2, 2},
  53             {+2, 2},
  54             {-Integer.MAX_VALUE, Integer.MAX_VALUE},
  55             {+Integer.MAX_VALUE, Integer.MAX_VALUE}
  56         };
  57 
  58         for(var testCase : testCases) {
  59             errors += testIntAbs(Math::abs,      testCase[0], testCase[1]);
  60             errors += testIntAbs(Math::absExact, testCase[0], testCase[1]);
  61         }
  62         return errors;
  63     }
  64 
  65     private static int testIntMinValue() {
  66         int errors = 0;
  67         // Strange but true
  68         errors += testIntAbs(Math::abs, Integer.MIN_VALUE, Integer.MIN_VALUE);
  69 
  70         // Test exceptional behavior for absExact
  71         try {
  72             int result = Math.absExact(Integer.MIN_VALUE);
  73             System.err.printf("Bad return value %d from Math.absExact(MIN_VALUE)%n",
  74                               result);
  75             errors++;
  76         } catch (ArithmeticException ae) {
  77             ; // Expected
  78         }
  79         return errors;
  80     }
  81 
  82     private static int testIntAbs(IntUnaryOperator absFunc,
  83                            int argument, int expected) {
  84         int result = absFunc.applyAsInt(argument);
  85         if (result != expected) {
  86             System.err.printf("Unexpected int abs result %d for argument %d%n",
  87                                 result, argument);
  88             return 1;
  89         } else {
  90             return 0;
  91         }
  92     }
  93 
  94     // --------------------------------------------------------------------
  95 
  96     private static long testInRangeLongAbs() {
  97         int errors = 0;
  98         long[][] testCases  = {
  99             // Argument to abs, expected result
 100             {+0L, 0L},
 101             {+1L, 1L},
 102             {-1L, 1L},
 103             {-2L, 2L},
 104             {+2L, 2L},
 105             {-Integer.MAX_VALUE, Integer.MAX_VALUE},
 106             {+Integer.MAX_VALUE, Integer.MAX_VALUE},
 107             { Integer.MIN_VALUE, -((long)Integer.MIN_VALUE)},
 108             {-Long.MAX_VALUE, Long.MAX_VALUE},
 109         };
 110 
 111         for(var testCase : testCases) {
 112             errors += testLongAbs(Math::abs,      testCase[0], testCase[1]);
 113             errors += testLongAbs(Math::absExact, testCase[0], testCase[1]);
 114         }
 115         return errors;
 116     }
 117 
 118     private static int testLongMinValue() {
 119         int errors = 0;
 120         // Strange but true
 121         errors += testLongAbs(Math::abs, Long.MIN_VALUE, Long.MIN_VALUE);
 122 
 123         // Test exceptional behavior for absExact
 124         try {
 125             long result = Math.absExact(Long.MIN_VALUE);
 126             System.err.printf("Bad return value %d from Math.absExact(MIN_VALUE)%n",
 127                               result);
 128             errors++;
 129         } catch (ArithmeticException ae) {
 130             ; // Expected
 131         }
 132         return errors;
 133     }
 134 
 135     private static int testLongAbs(LongUnaryOperator absFunc,
 136                            long argument, long expected) {
 137         long result = absFunc.applyAsLong(argument);
 138         if (result != expected) {
 139             System.err.printf("Unexpected long abs result %d for argument %d%n",
 140                                 result, argument);
 141             return 1;
 142         } else {
 143             return 0;
 144         }
 145     }
 146 }