1 /* 2 * Copyright (c) 2019, 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 /* 25 * @test 26 * @bug 8211936 27 * @summary Tests of BigDecimal.intValue() and BigDecimal.longValue() 28 */ 29 import java.math.BigDecimal; 30 import java.util.Map; 31 32 public class IntegralValueTests { main(String... args)33 public static void main(String... args) { 34 int failures = 35 integralValuesTest(INT_VALUES, true) + 36 integralValuesTest(LONG_VALUES, false); 37 if (failures != 0) { 38 throw new RuntimeException 39 ("Incurred " + failures + " failures for {int,long}Value()."); 40 } 41 } 42 43 private static final Map<BigDecimal, Number> INT_VALUES = 44 Map.ofEntries( 45 46 // 2**31 - 1 47 Map.entry(new BigDecimal("2147483647"), Integer.MAX_VALUE), 48 Map.entry(new BigDecimal("2147483647.0"), Integer.MAX_VALUE), 49 Map.entry(new BigDecimal("2147483647.00"), Integer.MAX_VALUE), 50 51 Map.entry(new BigDecimal("-2147483647"), -Integer.MAX_VALUE), 52 Map.entry(new BigDecimal("-2147483647.0"), -Integer.MAX_VALUE), 53 54 // -2**31 55 Map.entry(new BigDecimal("-2147483648"), Integer.MIN_VALUE), 56 Map.entry(new BigDecimal("-2147483648.1"), Integer.MIN_VALUE), 57 Map.entry(new BigDecimal("-2147483648.01"), Integer.MIN_VALUE), 58 59 // -2**31 + 1 truncation to 2**31 - 1 60 Map.entry(new BigDecimal("-2147483649"), Integer.MAX_VALUE), 61 62 // 2**64 - 1 truncation to 1 63 Map.entry(new BigDecimal("4294967295"), -1), 64 65 // 2**64 truncation to 0 66 Map.entry(new BigDecimal("4294967296"), 0), 67 68 // Fast path truncation to 0 69 Map.entry(new BigDecimal("1e32"), 0), 70 71 // Slow path truncation to -2**31 72 Map.entry(new BigDecimal("1e31"), Integer.MIN_VALUE), 73 74 // Slow path 75 Map.entry(new BigDecimal("1e0"), 1), 76 77 // Fast path round to 0 78 Map.entry(new BigDecimal("9e-1"), 0), 79 80 // Some random values 81 Map.entry(new BigDecimal("900e-1"), 90), // Increasing negative exponents 82 Map.entry(new BigDecimal("900e-2"), 9), 83 Map.entry(new BigDecimal("900e-3"), 0), 84 85 // Fast path round to 0 86 Map.entry(new BigDecimal("123456789e-9"), 0), 87 88 // Slow path round to 1 89 Map.entry(new BigDecimal("123456789e-8"), 1), 90 91 // Increasing positive exponents 92 Map.entry(new BigDecimal("10000001e1"), 100000010), 93 Map.entry(new BigDecimal("10000001e10"), -1315576832), 94 Map.entry(new BigDecimal("10000001e100"), 0), 95 Map.entry(new BigDecimal("10000001e1000"), 0), 96 Map.entry(new BigDecimal("10000001e10000"), 0), 97 Map.entry(new BigDecimal("10000001e100000"), 0), 98 Map.entry(new BigDecimal("10000001e1000000"), 0), 99 Map.entry(new BigDecimal("10000001e10000000"), 0), 100 Map.entry(new BigDecimal("10000001e100000000"), 0), 101 Map.entry(new BigDecimal("10000001e1000000000"), 0), 102 103 // Increasing negative exponents 104 Map.entry(new BigDecimal("10000001e-1"), 1000000), 105 Map.entry(new BigDecimal("10000001e-10"), 0), 106 Map.entry(new BigDecimal("10000001e-100"), 0), 107 Map.entry(new BigDecimal("10000001e-1000"), 0), 108 Map.entry(new BigDecimal("10000001e-10000"), 0), 109 Map.entry(new BigDecimal("10000001e-100000"), 0), 110 Map.entry(new BigDecimal("10000001e-1000000"), 0), 111 Map.entry(new BigDecimal("10000001e-10000000"), 0), 112 Map.entry(new BigDecimal("10000001e-100000000"), 0), 113 Map.entry(new BigDecimal("10000001e-1000000000"), 0), 114 115 // Currency calculation to 4 places 116 Map.entry(new BigDecimal("12345.0001"), 12345), 117 Map.entry(new BigDecimal("12345.9999"), 12345), 118 Map.entry(new BigDecimal("-12345.0001"), -12345), 119 Map.entry(new BigDecimal("-12345.9999"), -12345)); 120 121 private static final Map<BigDecimal, Number> LONG_VALUES = 122 Map.ofEntries( 123 // 2**63 - 1 124 Map.entry(new BigDecimal("9223372036854775807"), Long.MAX_VALUE), 125 Map.entry(new BigDecimal("9223372036854775807.0"), Long.MAX_VALUE), 126 Map.entry(new BigDecimal("9223372036854775807.00"), Long.MAX_VALUE), 127 128 // 2**63 truncation to -2**63 129 Map.entry(new BigDecimal("-9223372036854775808"), Long.MIN_VALUE), 130 Map.entry(new BigDecimal("-9223372036854775808.1"), Long.MIN_VALUE), 131 Map.entry(new BigDecimal("-9223372036854775808.01"), Long.MIN_VALUE), 132 133 // -2**63 + 1 truncation to 2**63 - 1 134 Map.entry(new BigDecimal("-9223372036854775809"), 9223372036854775807L), 135 136 // 2**64 - 1 truncation to -1 137 Map.entry(new BigDecimal("18446744073709551615"), -1L), 138 139 // 2**64 truncation to 0 140 Map.entry(new BigDecimal("18446744073709551616"), 0L), 141 142 // Slow path truncation to -2**63 143 Map.entry(new BigDecimal("1e63"), -9223372036854775808L), 144 Map.entry(new BigDecimal("-1e63"), -9223372036854775808L), 145 // Fast path with larger magnitude scale 146 Map.entry(new BigDecimal("1e64"), 0L), 147 Map.entry(new BigDecimal("-1e64"), 0L), 148 Map.entry(new BigDecimal("1e65"), 0L), 149 Map.entry(new BigDecimal("-1e65"), 0L), 150 151 // Slow path 152 Map.entry(new BigDecimal("1e0"), 1L), 153 154 // Fast path round to 0 155 Map.entry(new BigDecimal("9e-1"), 0L), 156 157 // Some random values 158 Map.entry(new BigDecimal("900e-1"), 90L), // Increasing negative exponents 159 Map.entry(new BigDecimal("900e-2"), 9L), 160 Map.entry(new BigDecimal("900e-3"), 0L), 161 162 // Fast path round to 0 163 Map.entry(new BigDecimal("123456789e-9"), 0L), 164 165 // Slow path round to 1 166 Map.entry(new BigDecimal("123456789e-8"), 1L), 167 168 // Increasing positive exponents 169 Map.entry(new BigDecimal("10000001e1"), 100000010L), 170 Map.entry(new BigDecimal("10000001e10"), 100000010000000000L), 171 Map.entry(new BigDecimal("10000001e100"), 0L), 172 Map.entry(new BigDecimal("10000001e1000"), 0L), 173 Map.entry(new BigDecimal("10000001e10000"), 0L), 174 Map.entry(new BigDecimal("10000001e100000"), 0L), 175 Map.entry(new BigDecimal("10000001e1000000"), 0L), 176 Map.entry(new BigDecimal("10000001e10000000"), 0L), 177 Map.entry(new BigDecimal("10000001e100000000"), 0L), 178 Map.entry(new BigDecimal("10000001e1000000000"), 0L), 179 180 // Increasing negative exponents 181 Map.entry(new BigDecimal("10000001e-1"), 1000000L), 182 Map.entry(new BigDecimal("10000001e-10"), 0L), 183 Map.entry(new BigDecimal("10000001e-100"), 0L), 184 Map.entry(new BigDecimal("10000001e-1000"), 0L), 185 Map.entry(new BigDecimal("10000001e-10000"), 0L), 186 Map.entry(new BigDecimal("10000001e-100000"), 0L), 187 Map.entry(new BigDecimal("10000001e-1000000"), 0L), 188 Map.entry(new BigDecimal("10000001e-10000000"), 0L), 189 Map.entry(new BigDecimal("10000001e-100000000"), 0L), 190 Map.entry(new BigDecimal("10000001e-1000000000"), 0L), 191 192 // Currency calculation to 4 places 193 Map.entry(new BigDecimal("12345.0001"), 12345L), 194 Map.entry(new BigDecimal("12345.9999"), 12345L), 195 Map.entry(new BigDecimal("-12345.0001"), -12345L), 196 Map.entry(new BigDecimal("-12345.9999"), -12345L)); 197 integralValuesTest(Map<BigDecimal, Number> v, boolean isInt)198 private static int integralValuesTest(Map<BigDecimal, Number> v, boolean isInt) { 199 System.err.format("Testing %s%n", isInt ? "Integer" : "Long"); 200 int failures = 0; 201 for (var testCase : v.entrySet()) { 202 BigDecimal bd = testCase.getKey(); 203 Number expected = testCase.getValue(); 204 try { 205 if (isInt) { 206 int intValue = bd.intValue(); 207 if (intValue != (int)expected) { 208 failures += reportError(bd, expected, intValue, isInt); 209 } 210 } else { 211 long longValue = bd.longValue(); 212 if (longValue != (long)expected) { 213 failures += reportError(bd, expected, longValue, isInt); 214 } 215 } 216 } catch (Exception e) { 217 failures++; 218 System.err.format("Unexpected exception %s for %s%n", 219 e, bd.toString()); 220 } 221 } 222 return failures; 223 } 224 reportError(BigDecimal bd, Number expected, long longValue, boolean isInt)225 private static int reportError(BigDecimal bd, Number expected, long longValue, boolean isInt) { 226 System.err.format("For %s, scale=%d, expected %d, actual %d, simple %d%n", 227 bd.toString(), bd.scale(), 228 (isInt ? (Integer) expected : (Long) expected ), 229 longValue, 230 (isInt ? simpleIntValue(bd): simpleLongValue(bd) )); 231 return 1; 232 } 233 simpleLongValue(BigDecimal bd)234 private static long simpleLongValue(BigDecimal bd) { 235 return bd.toBigInteger().longValue(); 236 } 237 simpleIntValue(BigDecimal bd)238 private static int simpleIntValue(BigDecimal bd) { 239 return bd.toBigInteger().intValue(); 240 } 241 } 242