|
1 | 1 | /* |
2 | | - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
21 | 21 | * questions. |
22 | 22 | */ |
23 | 23 |
|
24 | | -import java.util.function.*; |
| 24 | +import java.util.concurrent.atomic.AtomicInteger; |
| 25 | +import java.util.function.DoubleUnaryOperator; |
| 26 | +import java.util.function.IntUnaryOperator; |
| 27 | +import java.util.function.LongUnaryOperator; |
| 28 | +import java.util.function.UnaryOperator; |
| 29 | +import java.util.stream.DoubleStream; |
| 30 | +import jdk.internal.math.DoubleConsts; |
| 31 | +import jdk.internal.math.FloatConsts; |
25 | 32 |
|
26 | 33 | /* |
27 | 34 | * @test |
28 | | - * @bug 8241374 |
| 35 | + * @bug 6506405 8241374 |
29 | 36 | * @summary Test abs and absExact for Math and StrictMath |
| 37 | + * @modules java.base/jdk.internal.math |
30 | 38 | */ |
31 | 39 | public class AbsTests { |
| 40 | + private static final double GELFOND = Math.exp(Math.PI); |
| 41 | + private static final double TAU = 2.0*Math.PI; |
| 42 | + |
| 43 | + // Values for testing float and double abs |
| 44 | + private static final double[] FLOATING_POINT_VALUES = new double[] { |
| 45 | + 0.0, |
| 46 | + -0.0, |
| 47 | + +0.0, |
| 48 | + Double.MIN_VALUE, |
| 49 | + Double.MIN_NORMAL, |
| 50 | + Double.NEGATIVE_INFINITY, |
| 51 | + Double.POSITIVE_INFINITY, |
| 52 | + Double.NaN, |
| 53 | + Float.MIN_VALUE, |
| 54 | + Float.MIN_NORMAL, |
| 55 | + Float.NEGATIVE_INFINITY, |
| 56 | + Float.POSITIVE_INFINITY, |
| 57 | + Float.NaN, |
| 58 | + Double.longBitsToDouble((1 << DoubleConsts.SIGNIFICAND_WIDTH) | |
| 59 | + ((1 << DoubleConsts.SIGNIFICAND_WIDTH) - 1)), |
| 60 | + DoubleConsts.MAG_BIT_MASK >>> 1, |
| 61 | + Float.intBitsToFloat((1 << FloatConsts.SIGNIFICAND_WIDTH) | |
| 62 | + ((1 << FloatConsts.SIGNIFICAND_WIDTH) - 1)), |
| 63 | + FloatConsts.MAG_BIT_MASK >>> 1, |
| 64 | + Math.E, |
| 65 | + GELFOND, |
| 66 | + Math.PI, |
| 67 | + TAU |
| 68 | + }; |
| 69 | + |
32 | 70 | private static int errors = 0; |
33 | 71 |
|
34 | 72 | public static void main(String... args) { |
35 | 73 | errors += testInRangeIntAbs(); |
36 | 74 | errors += testIntMinValue(); |
37 | 75 | errors += testInRangeLongAbs(); |
38 | 76 | errors += testLongMinValue(); |
| 77 | + errors += testFloatAbs(); |
| 78 | + errors += testDoubleAbs(); |
39 | 79 |
|
40 | 80 | if (errors > 0) { |
41 | 81 | throw new RuntimeException(errors + " errors found testing abs."); |
42 | 82 | } |
43 | 83 | } |
44 | 84 |
|
| 85 | + // -------------------------------------------------------------------- |
| 86 | + |
45 | 87 | private static int testInRangeIntAbs() { |
46 | 88 | int errors = 0; |
47 | 89 | int[][] testCases = { |
@@ -143,4 +185,65 @@ private static int testLongAbs(LongUnaryOperator absFunc, |
143 | 185 | return 0; |
144 | 186 | } |
145 | 187 | } |
| 188 | + |
| 189 | + // -------------------------------------------------------------------- |
| 190 | + |
| 191 | + private static int testFloatAbs() { |
| 192 | + DoubleStream doubles = DoubleStream.of(FLOATING_POINT_VALUES); |
| 193 | + |
| 194 | + final AtomicInteger errors = new AtomicInteger(); |
| 195 | + doubles.mapToObj(d -> (float)d). |
| 196 | + forEach(f -> {errors.addAndGet(testFloatAbs(f));}); |
| 197 | + |
| 198 | + return errors.get(); |
| 199 | + } |
| 200 | + |
| 201 | + private static int testFloatAbs(float f) { |
| 202 | + int errors = testFloatAbs("Math.abs", Math::abs, f); |
| 203 | + errors += testFloatAbs("Math.abs", Math::abs, -f); |
| 204 | + errors += testFloatAbs("StrictMath.abs", StrictMath::abs, f); |
| 205 | + errors += testFloatAbs("StrictMath.abs", StrictMath::abs, -f); |
| 206 | + return errors; |
| 207 | + } |
| 208 | + |
| 209 | + private static int testFloatAbs(String testName, |
| 210 | + UnaryOperator<Float> absFunc, float f) { |
| 211 | + float result = absFunc.apply(-f); |
| 212 | + if (Float.isNaN(f) && Float.isNaN(result)) { |
| 213 | + return 0; |
| 214 | + } |
| 215 | + |
| 216 | + float expected = f == -0.0F ? 0.0F : (f < 0.0F ? -f : f); |
| 217 | + return Tests.test(testName, f, result, expected); |
| 218 | + } |
| 219 | + |
| 220 | + // -------------------------------------------------------------------- |
| 221 | + |
| 222 | + private static int testDoubleAbs() { |
| 223 | + DoubleStream doubles = DoubleStream.of(FLOATING_POINT_VALUES); |
| 224 | + |
| 225 | + final AtomicInteger errors = new AtomicInteger(); |
| 226 | + doubles.forEach(d -> {errors.addAndGet(testDoubleAbs(d));}); |
| 227 | + |
| 228 | + return errors.get(); |
| 229 | + } |
| 230 | + |
| 231 | + private static int testDoubleAbs(double d) { |
| 232 | + int errors = testDoubleAbs("Math.abs", Math::abs, d); |
| 233 | + errors += testDoubleAbs("Math.abs", Math::abs, -d); |
| 234 | + errors += testDoubleAbs("StrictMath.abs", StrictMath::abs, d); |
| 235 | + errors += testDoubleAbs("StrictMath.abs", StrictMath::abs, -d); |
| 236 | + return errors; |
| 237 | + } |
| 238 | + |
| 239 | + private static int testDoubleAbs(String testName, |
| 240 | + DoubleUnaryOperator absFunc, double d) { |
| 241 | + double result = absFunc.applyAsDouble(-d); |
| 242 | + if (Double.isNaN(d) && Double.isNaN(result)) { |
| 243 | + return 0; |
| 244 | + } |
| 245 | + |
| 246 | + double expected = d == -0.0F ? 0.0F : (d < 0.0F ? -d : d); |
| 247 | + return Tests.test(testName, d, result, expected); |
| 248 | + } |
146 | 249 | } |
0 commit comments