1 /* 2 * Copyright (c) 2012, 2013, 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 /* @test 25 * 26 * @bug 7131459 27 * @summary test various situations of NumberFormat rounding when close to tie 28 * @author Olivier Lagneau 29 * @run main TieRoundingTest 30 * 31 */ 32 33 import java.math.BigDecimal; 34 import java.math.BigInteger; 35 import java.text.NumberFormat; 36 import java.text.DecimalFormat; 37 import java.math.RoundingMode; 38 import java.util.Locale; 39 40 public class TieRoundingTest { 41 42 static int testCounter = 0; 43 static int errorCounter = 0; 44 static boolean allPassed = true; 45 46 static void formatOutputTestDouble(NumberFormat nf, 47 double doubleToTest, 48 String tiePosition, 49 String inputDigits, 50 String expectedOutput) { 51 52 int mfd = nf.getMaximumFractionDigits(); 53 RoundingMode rm = nf.getRoundingMode(); 54 String result = nf.format(doubleToTest); 55 56 if (!result.equals(expectedOutput)) { 57 System.out.println(); 58 System.out.println("========================================"); 59 System.out.println("***Error formatting double value from string : " + 60 inputDigits); 61 System.out.println("NumberFormat pattern is : " + 62 ((DecimalFormat ) nf).toPattern()); 63 System.out.println("Maximum number of fractional digits : " + mfd); 64 System.out.println("Fractional rounding digit : " + (mfd + 1)); 65 System.out.println("Position of value relative to tie : " + tiePosition); 66 System.out.println("Rounding Mode : " + rm); 67 System.out.println("BigDecimal output : " + 68 new BigDecimal(doubleToTest).toString()); 69 System.out.println("FloatingDecimal output : " + doubleToTest); 70 System.out.println( 71 "Error. Formatted result different from expected." + 72 "\nExpected output is : \"" + expectedOutput + "\"" + 73 "\nFormated output is : \"" + result + "\""); 74 System.out.println("========================================"); 75 System.out.println(); 76 77 errorCounter++; 78 allPassed = false; 79 } else { 86 System.out.print(", fract digits : " + mfd); 87 System.out.print(", position : " + tiePosition + " tie"); 88 System.out.print(", result : " + result); 89 System.out.println(", expected : " + expectedOutput); 90 } 91 } 92 93 static void formatOutputTestLong(NumberFormat nf, 94 long longToTest, 95 String tiePosition, 96 String inputDigits, 97 String expectedOutput) { 98 99 int mfd = nf.getMaximumFractionDigits(); 100 RoundingMode rm = nf.getRoundingMode(); 101 String result = nf.format(longToTest); 102 103 if (!result.equals(expectedOutput)) { 104 System.out.println(); 105 System.out.println("========================================"); 106 System.out.println("***Error formatting double value from string : " + 107 inputDigits); 108 System.out.println("NumberFormat pattern is : " + 109 ((DecimalFormat ) nf).toPattern()); 110 System.out.println("Maximum number of fractional digits : " + mfd); 111 System.out.println("Fractional rounding digit : " + (mfd + 1)); 112 System.out.println("Position of value relative to tie : " + tiePosition); 113 System.out.println("Rounding Mode : " + rm); 114 System.out.println( 115 "Error. Formatted result different from expected." + 116 "\nExpected output is : \"" + expectedOutput + "\"" + 117 "\nFormated output is : \"" + result + "\""); 118 System.out.println("========================================"); 119 System.out.println(); 120 121 errorCounter++; 122 allPassed = false; 123 } else { 124 testCounter++; 125 System.out.print("Success. Long input :" + inputDigits); 126 System.out.print(", rounding : " + rm); 127 System.out.print(", fract digits : " + mfd); 128 System.out.print(", tie position : " + tiePosition); 129 System.out.println(", expected : " + expectedOutput); 130 131 } 132 } 133 134 static void formatOutputTestObject(NumberFormat nf, 135 Object someNumber, 136 String tiePosition, 137 String inputDigits, 138 String expectedOutput) { 139 140 int mfd = nf.getMaximumFractionDigits(); 141 RoundingMode rm = nf.getRoundingMode(); 142 String result = nf.format(someNumber); 143 144 if (!result.equals(expectedOutput)) { 145 System.out.println(); 146 System.out.println("========================================"); 147 System.out.println("***Error formatting number value from string : " + 148 inputDigits); 149 System.out.println("NumberFormat pattern is : " + 150 ((DecimalFormat ) nf).toPattern()); 151 System.out.println("Maximum number of fractional digits : " + mfd); 152 System.out.println("Fractional rounding digit : " + (mfd + 1)); 153 System.out.println("Position of value relative to tie : " + tiePosition); 154 System.out.println("Rounding Mode : " + rm); 155 System.out.println("Number self output representation: " + someNumber); 156 System.out.println( 157 "Error. Formatted result different from expected." + 158 "\nExpected output is : \"" + expectedOutput + "\"" + 159 "\nFormated output is : \"" + result + "\""); 160 System.out.println("========================================"); 161 System.out.println(); 162 163 errorCounter++; 164 allPassed = false; 165 } else { 166 testCounter++; 167 System.out.print("Success. Number input :" + inputDigits); 168 System.out.print(", rounding : " + rm); 169 System.out.print(", fract digits : " + mfd); 170 System.out.print(", tie position : " + tiePosition); 171 System.out.println(", expected : " + expectedOutput); 172 } 173 } 174 175 public static void main(String[] args) { 176 177 // Only the 3 rounding modes below may be impacted by bug 7131459. 178 // So we do not test the other rounding modes. 179 RoundingMode[] roundingModes = { 180 RoundingMode.HALF_DOWN, 181 RoundingMode.HALF_EVEN, 182 RoundingMode.HALF_UP 183 }; 184 185 // Precise the relative position of input value against its closest tie. 186 String[] tieRelativePositions = { 187 "below", "exact", "above", 188 "below", "exact", "above", 189 "below", "exact", "above", 190 "below", "exact", "above" 191 }; 192 193 // =============== Testing double (and thus float) value cases ========= 194 195 System.out.println("\n===== testing 3 digits rounding position ====="); 196 double[] values3FractDigits = { 197 // unimpacting values close to tie, with less than 3 input fract digits 198 1.115d, 1.125d, 1.135d, 199 // impacting close to tie values covering all 6 cases 200 0.3115d, 0.3125d, 0.3135d, 201 0.6865d, 0.6875d, 0.6885d, 202 // unimpacting values close to tie, with more than 3 input fract digits 203 1.46885d, 2.46875d, 1.46865d 204 }; 205 206 String[] inputs3FractDigits = { 207 "1.115d", "1.125d", "1.135d", 208 "0.3115d", "0.3125d", "0.3135d", 209 "0.6865d", "0.6875d", "0.6885d", 210 "1.46885d", "2.46875d", "1.46865d" 211 }; 212 213 String[][] expected3FractDigits = { 214 {"1.115", "1.125", "1.135", 215 "0.311", "0.312", "0.314", 216 "0.686", "0.687", "0.689", 217 "1.469", "2.469", "1.469" 218 }, 219 {"1.115", "1.125", "1.135", 220 "0.311", "0.312", "0.314", 221 "0.686", "0.688", "0.689", 222 "1.469", "2.469", "1.469" 223 }, 224 {"1.115", "1.125", "1.135", 225 "0.311", "0.313", "0.314", 226 "0.686", "0.688", "0.689", 227 "1.469", "2.469", "1.469" 228 }, 229 }; 230 231 232 for (int r = 0; r < roundingModes.length; r++) { 233 NumberFormat dfDefault = NumberFormat.getInstance(Locale.US); 234 RoundingMode rmode = roundingModes[r]; 235 dfDefault.setRoundingMode(rmode); 236 System.out.println("\n----- Now checking " + rmode + 237 " rounding mode -----"); 238 239 for (int i = 0; i < values3FractDigits.length; i++) { 240 double d = values3FractDigits[i]; 241 String tiePosition = tieRelativePositions[i]; 242 String input = inputs3FractDigits[i]; 243 String expected = expected3FractDigits[r][i]; 244 245 formatOutputTestDouble(dfDefault, d, tiePosition, input, expected); 246 } 247 } 248 249 System.out.println("\n===== testing 5 digits rounding position ====="); 250 double[] values5FractDigits = { 251 // unimpacting values close to tie, with less than 5 input fract digits 252 1.3135d, 1.3125d, 1.3115d, 253 // impacting values close to tie, covering all 6 cases 254 1.328115d, 1.328125d, 1.328135d, 255 1.796865d, 1.796875d, 1.796885d, 256 // unimpacting values close to tie, with more than 5 input fract digits 257 1.3281149999999d, 1.75390625d, 1.7968750000001d 258 }; 259 260 String[] inputs5FractDigits = { 261 "1.3135d", "1.3125d", "1.3115d", 262 "1.328115d", "1.328125d", "1.328135d", 263 "1.796865d", "1.796875d", "1.796885d", 264 "1.3281149999999d", "1.75390625d", "1.7968750000001d" 265 }; 266 267 String[][] expected5FractDigits = { 268 {"1.3135", "1.3125", "1.3115", 269 "1.32811", "1.32812", "1.32814", 270 "1.79686", "1.79687", "1.79689", 271 "1.32811", "1.75391", "1.79688" 272 }, 273 {"1.3135", "1.3125", "1.3115", 274 "1.32811", "1.32812", "1.32814", 275 "1.79686", "1.79688", "1.79689", 276 "1.32811", "1.75391", "1.79688" 277 }, 278 {"1.3135", "1.3125", "1.3115", 279 "1.32811", "1.32813", "1.32814", 280 "1.79686", "1.79688", "1.79689", 281 "1.32811", "1.75391", "1.79688" 282 } 283 }; 284 285 286 for (int r = 0; r < roundingModes.length; r++) { 287 DecimalFormat df5 = (DecimalFormat) NumberFormat.getInstance(Locale.US); 288 RoundingMode rmode = roundingModes[r]; 289 df5.setRoundingMode(rmode); 290 System.out.println("\n----- Now checking " + rmode + 291 " rounding mode -----"); 292 df5.applyPattern("#,###.#####"); 293 294 for (int i = 0; i < values5FractDigits.length; i++) { 295 double d = values5FractDigits[i]; 296 String tiePosition = tieRelativePositions[i]; 297 String input = inputs5FractDigits[i]; 298 String expected = expected5FractDigits[r][i]; 299 300 formatOutputTestDouble(df5, d, tiePosition, input, expected); | 1 /* 2 * Copyright (c) 2012, 2014, 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 /* @test 25 * 26 * @bug 7131459 8039915 27 * @summary test various situations of NumberFormat rounding when close to tie 28 * @author Olivier Lagneau 29 * @run main TieRoundingTest 30 * 31 */ 32 33 import java.math.BigDecimal; 34 import java.math.BigInteger; 35 import java.text.NumberFormat; 36 import java.text.DecimalFormat; 37 import java.math.RoundingMode; 38 import java.util.Locale; 39 40 public class TieRoundingTest { 41 42 static int testCounter = 0; 43 static int errorCounter = 0; 44 static boolean allPassed = true; 45 46 static void formatOutputTestDouble(NumberFormat nf, 47 double doubleToTest, 48 String tiePosition, 49 String inputDigits, 50 String expectedOutput) { 51 52 int mfd = nf.getMaximumFractionDigits(); 53 RoundingMode rm = nf.getRoundingMode(); 54 String result = nf.format(doubleToTest); 55 56 if (!result.equals(expectedOutput)) { 57 System.out.println(); 58 System.out.println("========================================"); 59 System.out.println("***Failure : error formatting value from string : " + 60 inputDigits); 61 System.out.println("NumberFormat pattern is : " + 62 ((DecimalFormat ) nf).toPattern()); 63 System.out.println("Maximum number of fractional digits : " + mfd); 64 System.out.println("Fractional rounding digit : " + (mfd + 1)); 65 System.out.println("Position of value relative to tie : " + tiePosition); 66 System.out.println("Rounding Mode : " + rm); 67 System.out.println("BigDecimal output : " + 68 new BigDecimal(doubleToTest).toString()); 69 System.out.println("FloatingDecimal output : " + doubleToTest); 70 System.out.println( 71 "Error. Formatted result different from expected." + 72 "\nExpected output is : \"" + expectedOutput + "\"" + 73 "\nFormated output is : \"" + result + "\""); 74 System.out.println("========================================"); 75 System.out.println(); 76 77 errorCounter++; 78 allPassed = false; 79 } else { 86 System.out.print(", fract digits : " + mfd); 87 System.out.print(", position : " + tiePosition + " tie"); 88 System.out.print(", result : " + result); 89 System.out.println(", expected : " + expectedOutput); 90 } 91 } 92 93 static void formatOutputTestLong(NumberFormat nf, 94 long longToTest, 95 String tiePosition, 96 String inputDigits, 97 String expectedOutput) { 98 99 int mfd = nf.getMaximumFractionDigits(); 100 RoundingMode rm = nf.getRoundingMode(); 101 String result = nf.format(longToTest); 102 103 if (!result.equals(expectedOutput)) { 104 System.out.println(); 105 System.out.println("========================================"); 106 System.out.println("***Failure : error formatting value from string : " + 107 inputDigits); 108 System.out.println("NumberFormat pattern is : " + 109 ((DecimalFormat ) nf).toPattern()); 110 System.out.println("Maximum number of fractional digits : " + mfd); 111 System.out.println("Fractional rounding digit : " + (mfd + 1)); 112 System.out.println("Position of value relative to tie : " + tiePosition); 113 System.out.println("Rounding Mode : " + rm); 114 System.out.println( 115 "Error. Formatted result different from expected." + 116 "\nExpected output is : \"" + expectedOutput + "\"" + 117 "\nFormated output is : \"" + result + "\""); 118 System.out.println("========================================"); 119 System.out.println(); 120 121 errorCounter++; 122 allPassed = false; 123 } else { 124 testCounter++; 125 System.out.print("Success. Long input :" + inputDigits); 126 System.out.print(", rounding : " + rm); 127 System.out.print(", fract digits : " + mfd); 128 System.out.print(", tie position : " + tiePosition); 129 System.out.println(", expected : " + expectedOutput); 130 131 } 132 } 133 134 static void formatOutputTestObject(NumberFormat nf, 135 Object someNumber, 136 String tiePosition, 137 String inputDigits, 138 String expectedOutput) { 139 140 int mfd = nf.getMaximumFractionDigits(); 141 RoundingMode rm = nf.getRoundingMode(); 142 String result = nf.format(someNumber); 143 144 if (!result.equals(expectedOutput)) { 145 System.out.println(); 146 System.out.println("========================================"); 147 System.out.println("***Failure : error formatting value from string : " + 148 inputDigits); 149 System.out.println("NumberFormat pattern is : " + 150 ((DecimalFormat ) nf).toPattern()); 151 System.out.println("Maximum number of fractional digits : " + mfd); 152 System.out.println("Fractional rounding digit : " + (mfd + 1)); 153 System.out.println("Position of value relative to tie : " + tiePosition); 154 System.out.println("Rounding Mode : " + rm); 155 System.out.println("Number self output representation: " + someNumber); 156 System.out.println( 157 "Error. Formatted result different from expected." + 158 "\nExpected output is : \"" + expectedOutput + "\"" + 159 "\nFormated output is : \"" + result + "\""); 160 System.out.println("========================================"); 161 System.out.println(); 162 163 errorCounter++; 164 allPassed = false; 165 } else { 166 testCounter++; 167 System.out.print("Success. Number input :" + inputDigits); 168 System.out.print(", rounding : " + rm); 169 System.out.print(", fract digits : " + mfd); 170 System.out.print(", tie position : " + tiePosition); 171 System.out.println(", expected : " + expectedOutput); 172 } 173 } 174 175 public static void main(String[] args) { 176 177 // The 3 HALF_* rounding modes are impacted by bugs 7131459, 8039915. 178 // So we do not test the other rounding modes. 179 RoundingMode[] roundingModes = { 180 RoundingMode.HALF_DOWN, 181 RoundingMode.HALF_EVEN, 182 RoundingMode.HALF_UP 183 }; 184 185 // Precise the relative position of input value against its closest tie. 186 // The double values tested below for 3 and 5 fractional digits must follow 187 // this scheme (position toward tie). 188 String[] tieRelativePositions = { 189 "below", "exact", "above", 190 "below", "exact", "above", 191 "below", "exact", "above", 192 "below", "above", "above", 193 "below", "below", "above", 194 "below", "exact", "above" 195 }; 196 197 // =============== Testing double (and thus float) value cases ========= 198 199 System.out.println("\n===== testing 3 digits rounding position ====="); 200 double[] values3FractDigits = { 201 // unimpacting values close to tie, with less than 3 input fract digits 202 1.115d, 1.125d, 1.135d, 203 // HALF_* impacting close to tie values covering all 6 tie cases 204 0.3115d, 0.3125d, 0.3135d, 205 0.6865d, 0.6875d, 0.6885d, 206 // specific HALF_UP close to tie values 207 0.3124d, 0.3126d, 0.3128d, 208 // specific HALF_DOWN close to tie values 209 0.6864d, 0.6865d, 0.6868d, 210 // unimpacting values close to tie, with more than 3 input fract digits 211 1.46885d, 2.46875d, 1.46865d 212 }; 213 214 String[] inputs3FractDigits = { 215 "1.115d", "1.125d", "1.135d", 216 "0.3115d", "0.3125d", "0.3135d", 217 "0.6865d", "0.6875d", "0.6885d", 218 "0.3124d", "0.3126d", "0.3128d", 219 "0.6864d", "0.6865d", "0.6868d", 220 "1.46885d", "2.46875d", "1.46865d" 221 }; 222 223 String[][] expected3FractDigits = { 224 {"1.115", "1.125", "1.135", 225 "0.311", "0.312", "0.314", 226 "0.686", "0.687", "0.689", 227 "0.312", "0.313", "0.313", 228 "0.686", "0.686", "0.687", 229 "1.469", "2.469", "1.469" 230 }, 231 {"1.115", "1.125", "1.135", 232 "0.311", "0.312", "0.314", 233 "0.686", "0.688", "0.689", 234 "0.312", "0.313", "0.313", 235 "0.686", "0.686", "0.687", 236 "1.469", "2.469", "1.469" 237 }, 238 {"1.115", "1.125", "1.135", 239 "0.311", "0.313", "0.314", 240 "0.686", "0.688", "0.689", 241 "0.312", "0.313", "0.313", 242 "0.686", "0.686", "0.687", 243 "1.469", "2.469", "1.469" 244 }, 245 }; 246 247 248 for (int r = 0; r < roundingModes.length; r++) { 249 NumberFormat dfDefault = NumberFormat.getInstance(Locale.US); 250 RoundingMode rmode = roundingModes[r]; 251 dfDefault.setRoundingMode(rmode); 252 System.out.println("\n----- Now checking " + rmode + 253 " rounding mode -----"); 254 255 for (int i = 0; i < values3FractDigits.length; i++) { 256 double d = values3FractDigits[i]; 257 String tiePosition = tieRelativePositions[i]; 258 String input = inputs3FractDigits[i]; 259 String expected = expected3FractDigits[r][i]; 260 261 formatOutputTestDouble(dfDefault, d, tiePosition, input, expected); 262 } 263 } 264 265 System.out.println("\n===== testing 5 digits rounding position ====="); 266 double[] values5FractDigits = { 267 // unimpacting values close to tie, with less than 5 input fract digits 268 1.3135d, 1.3125d, 1.3115d, 269 // HALF_* impacting values close to tie, covering all 6 cases 270 1.328115d, 1.328125d, 1.328135d, 271 1.796865d, 1.796875d, 1.796885d, 272 // specific HALF_UP close to tie values 273 1.328124d, 1.798876d, 1.796889d, 274 // specific HALF_DOWN close to tie values 275 1.328114d, 1.796865d, 1.328138d, 276 // unimpacting values close to tie, with more than 5 input fract digits 277 1.3281149999999d, 1.75390625d, 1.7968750000001d 278 }; 279 280 String[] inputs5FractDigits = { 281 "1.3135d", "1.3125d", "1.3115d", 282 "1.328115d", "1.328125d", "1.328135d", 283 "1.796865d", "1.796875d", "1.796885d", 284 "1.328124d", "1.798876d", "1.796889d", 285 "1.328114d", "1.796865d", "1.328138d", 286 "1.3281149999999d", "1.75390625d", "1.7968750000001d" 287 }; 288 289 String[][] expected5FractDigits = { 290 {"1.3135", "1.3125", "1.3115", 291 "1.32811", "1.32812", "1.32814", 292 "1.79686", "1.79687", "1.79689", 293 "1.32812", "1.79888", "1.79689", 294 "1.32811", "1.79686", "1.32814", 295 "1.32811", "1.75391", "1.79688" 296 }, 297 {"1.3135", "1.3125", "1.3115", 298 "1.32811", "1.32812", "1.32814", 299 "1.79686", "1.79688", "1.79689", 300 "1.32812", "1.79888", "1.79689", 301 "1.32811", "1.79686", "1.32814", 302 "1.32811", "1.75391", "1.79688" 303 }, 304 {"1.3135", "1.3125", "1.3115", 305 "1.32811", "1.32813", "1.32814", 306 "1.79686", "1.79688", "1.79689", 307 "1.32812", "1.79888", "1.79689", 308 "1.32811", "1.79686", "1.32814", 309 "1.32811", "1.75391", "1.79688" 310 } 311 }; 312 313 314 for (int r = 0; r < roundingModes.length; r++) { 315 DecimalFormat df5 = (DecimalFormat) NumberFormat.getInstance(Locale.US); 316 RoundingMode rmode = roundingModes[r]; 317 df5.setRoundingMode(rmode); 318 System.out.println("\n----- Now checking " + rmode + 319 " rounding mode -----"); 320 df5.applyPattern("#,###.#####"); 321 322 for (int i = 0; i < values5FractDigits.length; i++) { 323 double d = values5FractDigits[i]; 324 String tiePosition = tieRelativePositions[i]; 325 String input = inputs5FractDigits[i]; 326 String expected = expected5FractDigits[r][i]; 327 328 formatOutputTestDouble(df5, d, tiePosition, input, expected); |