1 /* 2 * Copyright (c) 2003, 2016, 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 4838107 8008577 27 * @summary Confirm that DecimalFormat can format a number with negative exponent number correctly. 28 * @library /java/text/testlib 29 * @run main/othervm -Djava.locale.providers=COMPAT,SPI Bug4838107 30 */ 31 32 import java.math.*; 33 import java.util.*; 34 import java.text.*; 35 36 public class Bug4838107 extends IntlTest { 37 38 static DecimalFormat df; 39 static DecimalFormatSymbols dfs; 40 static boolean err = false; 41 42 static public void main(String[] args) { 43 Locale defaultLoc = Locale.getDefault(); 44 Locale.setDefault(Locale.US); 45 46 /** 47 * This bug is about exponential formatting. But I added test cases for: 48 * - Double and BigDecimal numbers which don't have exponent parts. 49 * - Long and BigInteger numbers which don't support exponential 50 * notation. 51 * because there are few test cases for suffix and prefix. 52 * And also, I added test cases to guarantee further formatting and 53 * parsing using the same DecimalFormat instance will not change the 54 * Number's value anymore. 55 */ 56 57 test_double(); 58 test_long(); 59 test_BigDecimal(); 60 test_BigInteger(); 61 62 Locale.setDefault(defaultLoc); 63 64 if (err) { 65 throw new RuntimeException("Wrong format with DecimalFormat"); 66 } 67 } 68 69 static void test_double() { 70 df = new DecimalFormat(); 71 dfs = df.getDecimalFormatSymbols(); 72 73 /* Test with default pattern */ 74 test(new Double(1234), "1,234"); 75 test(new Double(0.1234), "0.123"); // rounded 76 test(new Double(-1234), "-1,234"); 77 test(new Double(-0.1234), "-0.123"); // rounded 78 79 test(new Double(Double.POSITIVE_INFINITY), "\u221e"); 80 test(new Double(Double.NEGATIVE_INFINITY), "-\u221e"); 81 test(new Double(Double.NaN), "\ufffd"); // without prefix and suffix 82 test(new Double(0.0), "0"); 83 test(new Double(-0.0), "-0"); // with the minus sign 84 85 /* Specify a pattern and the minus sign. */ 86 prepareFormatter("<P>#.###E00<S>", 'm'); 87 test(new Double(1234), "<P>1.234E03<S>"); 88 test(new Double(0.1234), "<P>1.234Em01<S>"); 89 test(new Double(-1234), "m<P>1.234E03<S>"); 90 test(new Double(-0.1234), "m<P>1.234Em01<S>"); 91 92 prepareFormatter("<P>#.###E00<S>;#.###E00", 'm'); 93 test(new Double(1234), "<P>1.234E03<S>"); 94 test(new Double(0.1234), "<P>1.234Em01<S>"); 95 test(new Double(-1234), "1.234E03"); 96 test(new Double(-0.1234), "1.234Em01"); 97 98 prepareFormatter("#.###E00;<P>#.###E00<S>", 'm'); 99 test(new Double(1234), "1.234E03"); 100 test(new Double(0.1234), "1.234Em01"); 101 test(new Double(-1234), "<P>1.234E03<S>"); 102 test(new Double(-0.1234), "<P>1.234Em01<S>"); 103 104 prepareFormatter("<P>#.###E00<S>;<p>-#.###E00<s>", 'm'); 105 test(new Double(1234), "<P>1.234E03<S>"); 106 test(new Double(0.1234), "<P>1.234Em01<S>"); 107 test(new Double(-1234), "<p>m1.234E03<s>"); 108 test(new Double(-0.1234), "<p>m1.234Em01<s>"); 109 110 test(new Double(Double.POSITIVE_INFINITY), "<P>\u221e<S>"); 111 test(new Double(Double.NEGATIVE_INFINITY), "<p>m\u221e<s>"); 112 test(new Double(Double.NaN), "\ufffd"); // without prefix and suffix 113 test(new Double(0.0), "<P>0E00<S>"); 114 test(new Double(-0.0), "<p>m0E00<s>"); // with the minus sign 115 } 116 117 static void test_BigDecimal() { 118 df = new DecimalFormat(); 119 dfs = df.getDecimalFormatSymbols(); 120 121 /* Test with default pattern */ 122 test(new BigDecimal("123456789012345678901234567890"), 123 "123,456,789,012,345,678,901,234,567,890"); 124 test(new BigDecimal("0.000000000123456789012345678901234567890"), 125 "0"); 126 test(new BigDecimal("-123456789012345678901234567890"), 127 "-123,456,789,012,345,678,901,234,567,890"); 128 test(new BigDecimal("-0.000000000123456789012345678901234567890"), 129 "-0"); 130 131 test(new BigDecimal("0"), "0"); 132 test(new BigDecimal("-0"), "0"); 133 134 /* Specify a pattern and the minus sign. */ 135 prepareFormatter("<P>#.####################E00<S>;<p>-#.####################E00<s>", 'm'); 136 test(new BigDecimal("123456789012345678901234567890"), 137 "<P>1.23456789012345678901E29<S>"); 138 test(new BigDecimal("0.000000000123456789012345678901234567890"), 139 "<P>1.23456789012345678901Em10<S>"); 140 test(new BigDecimal("-123456789012345678901234567890"), 141 "<p>m1.23456789012345678901E29<s>"); 142 test(new BigDecimal("-0.000000000123456789012345678901234567890"), 143 "<p>m1.23456789012345678901Em10<s>"); 144 145 test(new BigDecimal("0"), "<P>0E00<S>"); 146 test(new BigDecimal("-0"), "<P>0E00<S>"); 147 } 148 149 static void test_long() { 150 df = new DecimalFormat(); 151 dfs = df.getDecimalFormatSymbols(); 152 153 /* Test with default pattern */ 154 test(new Long(123456789), "123,456,789"); 155 test(new Long(-123456789), "-123,456,789"); 156 157 test(new Long(0), "0"); 158 test(new Long(-0), "0"); 159 160 /* Specify a pattern and the minus sign. */ 161 prepareFormatter("<P>#,###<S>;<p>-#,###<s>", 'm'); 162 test(new Long(123456789), "<P>123,456,789<S>"); 163 test(new Long(-123456789), "<p>m123,456,789<s>"); 164 165 test(new Long(0), "<P>0<S>"); 166 test(new Long(-0), "<P>0<S>"); 167 } 168 169 static void test_BigInteger() { 170 df = new DecimalFormat(); 171 dfs = df.getDecimalFormatSymbols(); 172 173 /* Test with default pattern */ 174 test(new BigInteger("123456789012345678901234567890"), 175 "123,456,789,012,345,678,901,234,567,890"); 176 test(new BigInteger("-123456789012345678901234567890"), 177 "-123,456,789,012,345,678,901,234,567,890"); 178 179 test(new BigInteger("0"), "0"); 180 test(new BigInteger("-0"), "0"); 181 182 /* Specify a pattern and the minus sign. */ 183 prepareFormatter("<P>#,###<S>;<p>-#,###<s>", 'm'); 184 test(new BigInteger("123456789012345678901234567890"), 185 "<P>123,456,789,012,345,678,901,234,567,890<S>"); 186 test(new BigInteger("-123456789012345678901234567890"), 187 "<p>m123,456,789,012,345,678,901,234,567,890<s>"); 188 189 test(new BigInteger("0"), "<P>0<S>"); 190 test(new BigInteger("-0"), "<P>0<S>"); 191 } 192 193 static void prepareFormatter(String pattern, char minusSign) { 194 dfs = df.getDecimalFormatSymbols(); 195 df.applyPattern(pattern); 196 dfs.setMinusSign(minusSign); 197 df.setDecimalFormatSymbols(dfs); 198 } 199 200 static void test(Number num, String str) { 201 String formatted = df.format(num); 202 if (!formatted.equals(str)) { 203 err = true; 204 System.err.println(" DecimalFormat format(" + 205 num.getClass().getName() + 206 ") error: \n\tnumber: " + num + 207 "\n\tminus sign: " + dfs.getMinusSign() + 208 "\n\tgot: " + formatted + 209 "\n\texpected: " + str); 210 return; 211 } 212 213 if (num instanceof BigDecimal || num instanceof BigInteger) { 214 df.setParseBigDecimal(true); 215 } 216 Number parsed1 = null, parsed2 = null; 217 try { 218 parsed1 = df.parse(formatted); 219 formatted = df.format(parsed1); 220 parsed2 = df.parse(formatted); 221 if (!parsed1.equals(parsed2)) { 222 err = true; 223 System.err.println(" DecimalFormat roundtrip parse(" + 224 num.getClass().getName() + 225 ") error: \n\toriginal number: " + str + 226 "\n\tparsed number: " + parsed1 + 227 " (" + parsed1.getClass().getName() + ")" + 228 "\n\tformatted number: " + formatted + 229 "\n\tre-parsed number: " + parsed2 + 230 " (" + parsed2.getClass().getName() + ")" + 231 "\n\tminus sign: " + dfs.getMinusSign()); 232 } 233 } 234 catch (Exception e) { 235 err = true; 236 System.err.println(" DecimalFormat parse(" + 237 num.getClass().getName() + 238 ") threw an Exception: " + e.getMessage() + 239 "\n\toriginal number: " + str + 240 "\n\tparsed number : " + parsed1 + 241 " (" + parsed1.getClass().getName() + ")" + 242 "\n\tformatted number: " + formatted + 243 "\n\tre-parsed number: " + parsed2 + 244 " (" + parsed2.getClass().getName() + ")" + 245 "\n\tminus sign: " + dfs.getMinusSign()); 246 } 247 } 248 }