1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.text.numbers;
18
19 import java.text.DecimalFormat;
20 import java.text.DecimalFormatSymbols;
21 import java.util.Locale;
22 import java.util.Random;
23 import java.util.function.DoubleFunction;
24 import java.util.function.Function;
25 import java.util.stream.Stream;
26
27 import org.junit.jupiter.api.Assertions;
28 import org.junit.jupiter.api.Test;
29 import org.junit.jupiter.params.ParameterizedTest;
30 import org.junit.jupiter.params.provider.Arguments;
31 import org.junit.jupiter.params.provider.MethodSource;
32
33 public class DoubleFormatTest {
34
35 private static void assertLocalizedFormatsAreEqual(final double d, final DecimalFormat df,
36 final DoubleFunction<String> fmt, final Locale loc) {
37
38
39
40
41 final String dfStr = trimFormatChars(df.format(d));
42 final String fmtStr = trimFormatChars(fmt.apply(d));
43
44 try {
45 Assertions.assertEquals(dfStr, fmtStr,
46 () -> "Unexpected output for locale [" + loc.toLanguageTag() + "] and double value " + d);
47 } catch (final AssertionError e) {
48
49
50
51
52
53
54
55
56
57 final DecimalFormatSymbols dfs = new DecimalFormatSymbols(loc);
58 final char decimalSeparator = dfs.getDecimalSeparator();
59 final char zeroDigit = dfs.getZeroDigit();
60 final String updated = fmtStr.replace(new String(new char[] {decimalSeparator, zeroDigit}), "");
61 if (dfStr.equals(updated)) {
62 return;
63 }
64 throw e;
65 }
66 }
67
68 private static void checkDefaultFormatSpecial(final DoubleFunction<String> fmt) {
69 checkFormat(fmt, 0.0, "0.0");
70 checkFormat(fmt, -0.0, "-0.0");
71 checkFormat(fmt, Double.NaN, "NaN");
72 checkFormat(fmt, Double.POSITIVE_INFINITY, "Infinity");
73 checkFormat(fmt, Double.NEGATIVE_INFINITY, "-Infinity");
74 }
75
76 private static void checkFormat(final DoubleFunction<String> fmt, final double d, final String str) {
77 Assertions.assertEquals(str, fmt.apply(d));
78 }
79
80
81
82
83
84
85
86 private static void checkFormatAccuracy(final DoubleFunction<String> fmt, final double d) {
87 final String str = fmt.apply(d);
88 final double parsed = Double.parseDouble(str);
89 Assertions.assertEquals(d, parsed, () -> "Formatted double string [" + str + "] did not match input value");
90 }
91
92
93
94
95
96
97
98
99 private static void checkFormatAccuracyWithDefaults(final DoubleFormat type) {
100 final DoubleFunction<String> fmt = type.builder().get();
101
102 checkDefaultFormatSpecial(fmt);
103
104 checkFormatAccuracy(fmt, Double.MIN_VALUE);
105 checkFormatAccuracy(fmt, -Double.MIN_VALUE);
106
107 checkFormatAccuracy(fmt, Double.MIN_NORMAL);
108 checkFormatAccuracy(fmt, -Double.MIN_NORMAL);
109
110 checkFormatAccuracy(fmt, Double.MAX_VALUE);
111 checkFormatAccuracy(fmt, -Double.MAX_VALUE);
112
113 checkFormatAccuracy(fmt, Math.PI);
114 checkFormatAccuracy(fmt, Math.E);
115
116 final Random rnd = new Random(10L);
117 final int cnt = 1000;
118 for (int i = 0; i < cnt; ++i) {
119 checkFormatAccuracy(fmt, randomDouble(rnd));
120 }
121 }
122
123 private static void checkLocalizedFormat(final Locale loc, final String pattern,
124 final Function<Locale, DoubleFunction<String>> factory) {
125
126 final DecimalFormat df = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance(loc));
127 final DoubleFunction<String> fmt = factory.apply(loc);
128
129
130 assertLocalizedFormatsAreEqual(0.0, df, fmt, loc);
131 assertLocalizedFormatsAreEqual(Double.POSITIVE_INFINITY, df, fmt, loc);
132 assertLocalizedFormatsAreEqual(Double.NEGATIVE_INFINITY, df, fmt, loc);
133 assertLocalizedFormatsAreEqual(Double.NaN, df, fmt, loc);
134
135 assertLocalizedFormatsAreEqual(1.0, df, fmt, loc);
136 assertLocalizedFormatsAreEqual(-1.0, df, fmt, loc);
137 assertLocalizedFormatsAreEqual(Math.PI, df, fmt, loc);
138 assertLocalizedFormatsAreEqual(Math.E, df, fmt, loc);
139
140
141
142
143
144
145
146
147
148
149 final Random rnd = new Random(12L);
150 final int minExp = -24;
151 final int maxExp = 24;
152 final int cnt = 1000;
153 for (int i = 0; i < cnt; ++i) {
154 assertLocalizedFormatsAreEqual(randomDouble(minExp, maxExp, rnd), df, fmt, loc);
155 }
156 }
157
158 private static void checkLocalizedFormats(final String pattern, final Function<Locale, DoubleFunction<String>> factory) {
159 for (final Locale loc : Locale.getAvailableLocales()) {
160 checkLocalizedFormat(loc, pattern, factory);
161 }
162 }
163
164
165
166
167
168
169
170
171 private static double randomDouble(final int minExp, final int maxExp, final Random rnd) {
172
173 final long mask = (1L << 52) - 1 | 1L << 63;
174 final long bits = rnd.nextLong() & mask;
175
176 final long exp = rnd.nextInt(maxExp - minExp + 1) + minExp + 1023;
177 return Double.longBitsToDouble(bits | exp << 52);
178 }
179
180
181
182
183
184
185 private static double randomDouble(final Random rnd) {
186 return randomDouble(Double.MIN_EXPONENT, Double.MAX_EXPONENT, rnd);
187 }
188
189 static Stream<Arguments> testMaximumPrecision() {
190 return Stream.of(
191
192
193
194 Arguments.of(DoubleFormat.PLAIN.builder().get(), -9.3540047119774374E17),
195 Arguments.of(DoubleFormat.SCIENTIFIC.builder().get(), -9.3540047119774374E17)
196 );
197 }
198
199
200
201
202
203
204 private static String trimFormatChars(final String str) {
205 final StringBuilder sb = new StringBuilder();
206 for (final char c : str.toCharArray()) {
207 if (Character.getType(c) != Character.FORMAT) {
208 sb.append(c);
209 }
210 }
211 return sb.toString();
212 }
213
214 @Test
215 void testBuilder_illegalArgs() {
216
217 final DoubleFormat.Builder builder = DoubleFormat.PLAIN.builder();
218
219
220 Assertions.assertThrows(NullPointerException.class, () -> builder.digits(null));
221 Assertions.assertThrows(IllegalArgumentException.class, () -> builder.digits("a"));
222 Assertions.assertThrows(IllegalArgumentException.class, () -> builder.digits("0123456789a"));
223
224 Assertions.assertThrows(NullPointerException.class, () -> builder.exponentSeparator(null));
225 Assertions.assertThrows(NullPointerException.class, () -> builder.infinity(null));
226 Assertions.assertThrows(NullPointerException.class, () -> builder.nan(null));
227 Assertions.assertThrows(NullPointerException.class, () -> builder.formatSymbols(null));
228 }
229
230 @Test
231 void testCustomDigitString() {
232
233 final String digits = "abcdefghij";
234 final DoubleFunction<String> plain = DoubleFormat.PLAIN.builder().digits(digits).get();
235 final DoubleFunction<String> sci = DoubleFormat.SCIENTIFIC.builder().digits(digits).get();
236 final DoubleFunction<String> eng = DoubleFormat.ENGINEERING.builder().digits(digits).get();
237 final DoubleFunction<String> mixed = DoubleFormat.MIXED.builder().digits(digits).get();
238
239
240 checkFormat(plain, 9876543210.0, "jihgfedcba.a");
241 checkFormat(sci, 9876543210.0, "j.ihgfedcbEj");
242 checkFormat(eng, 9876543210.0, "j.ihgfedcbEj");
243 checkFormat(mixed, 9876543210.0, "j.ihgfedcbEj");
244 }
245
246 @Test
247 void testEngineering_custom() {
248
249 final DoubleFunction<String> fmt = DoubleFormat.ENGINEERING.builder()
250 .maxPrecision(3)
251 .minDecimalExponent(-3)
252 .allowSignedZero(false)
253 .includeFractionPlaceholder(false)
254 .decimalSeparator(',')
255 .exponentSeparator("e")
256 .infinity("inf")
257 .nan("nan")
258 .minusSign('!')
259 .get();
260
261
262 checkFormat(fmt, Double.NaN, "nan");
263 checkFormat(fmt, Double.POSITIVE_INFINITY, "inf");
264 checkFormat(fmt, Double.NEGATIVE_INFINITY, "!inf");
265
266 checkFormat(fmt, 0.00001, "0");
267 checkFormat(fmt, -0.0001, "0");
268 checkFormat(fmt, 0.001, "1e!3");
269 checkFormat(fmt, -0.01, "!10e!3");
270 checkFormat(fmt, 0.1, "100e!3");
271 checkFormat(fmt, -0.0, "0");
272 checkFormat(fmt, 0.0, "0");
273 checkFormat(fmt, -1.0, "!1");
274 checkFormat(fmt, 10.0, "10");
275 checkFormat(fmt, -100.0, "!100");
276 checkFormat(fmt, 1000.0, "1e3");
277 checkFormat(fmt, -10000.0, "!10e3");
278 checkFormat(fmt, 100000.0, "100e3");
279 checkFormat(fmt, -1000000.0, "!1e6");
280 checkFormat(fmt, 10000000.0, "10e6");
281 checkFormat(fmt, -100000000.0, "!100e6");
282
283 checkFormat(fmt, 1.25e-3, "1e!3");
284 checkFormat(fmt, -9.975e-4, "!1e!3");
285 checkFormat(fmt, 12345, "12,3e3");
286 checkFormat(fmt, -9_999_999, "!10e6");
287 checkFormat(fmt, 1.00001e7, "10e6");
288
289 checkFormat(fmt, Double.MAX_VALUE, "180e306");
290 checkFormat(fmt, Double.MIN_VALUE, "0");
291 checkFormat(fmt, Double.MIN_NORMAL, "0");
292 checkFormat(fmt, Math.PI, "3,14");
293 checkFormat(fmt, Math.E, "2,72");
294 }
295
296 @Test
297 void testEngineering_defaults() {
298
299 final DoubleFunction<String> fmt = DoubleFormat.ENGINEERING.builder()
300 .get();
301
302
303 checkDefaultFormatSpecial(fmt);
304
305 checkFormat(fmt, 0.00001, "10.0E-6");
306 checkFormat(fmt, -0.0001, "-100.0E-6");
307 checkFormat(fmt, 0.001, "1.0E-3");
308 checkFormat(fmt, -0.01, "-10.0E-3");
309 checkFormat(fmt, 0.1, "100.0E-3");
310 checkFormat(fmt, -0.0, "-0.0");
311 checkFormat(fmt, 0.0, "0.0");
312 checkFormat(fmt, -1.0, "-1.0");
313 checkFormat(fmt, 10.0, "10.0");
314 checkFormat(fmt, -100.0, "-100.0");
315 checkFormat(fmt, 1000.0, "1.0E3");
316 checkFormat(fmt, -10000.0, "-10.0E3");
317 checkFormat(fmt, 100000.0, "100.0E3");
318 checkFormat(fmt, -1000000.0, "-1.0E6");
319 checkFormat(fmt, 10000000.0, "10.0E6");
320 checkFormat(fmt, -100000000.0, "-100.0E6");
321
322 checkFormat(fmt, 1.25e-3, "1.25E-3");
323 checkFormat(fmt, -9.975e-4, "-997.5E-6");
324 checkFormat(fmt, 12345, "12.345E3");
325 checkFormat(fmt, -9_999_999, "-9.999999E6");
326 checkFormat(fmt, 1.00001e7, "10.0001E6");
327
328 checkFormat(fmt, Double.MAX_VALUE, "179.76931348623157E306");
329 checkFormat(fmt, Double.MIN_VALUE, "4.9E-324");
330 checkFormat(fmt, Double.MIN_NORMAL, "22.250738585072014E-309");
331 checkFormat(fmt, Math.PI, "3.141592653589793");
332 checkFormat(fmt, Math.E, "2.718281828459045");
333 }
334
335 @Test
336 void testEngineering_localeFormatComparison() {
337
338 checkLocalizedFormats("##0.0##E0", loc -> DoubleFormat.ENGINEERING.builder()
339 .maxPrecision(6)
340 .alwaysIncludeExponent(true)
341 .formatSymbols(DecimalFormatSymbols.getInstance(loc))
342 .get());
343 }
344
345 @Test
346 void testFormatAccuracy() {
347
348 checkFormatAccuracyWithDefaults(DoubleFormat.PLAIN);
349 checkFormatAccuracyWithDefaults(DoubleFormat.MIXED);
350 checkFormatAccuracyWithDefaults(DoubleFormat.SCIENTIFIC);
351 checkFormatAccuracyWithDefaults(DoubleFormat.ENGINEERING);
352 }
353
354
355
356
357
358
359
360
361 @ParameterizedTest
362 @MethodSource
363 void testMaximumPrecision(final DoubleFunction<String> fmt, final double value) {
364 final String s = fmt.apply(value);
365 final double d = Double.parseDouble(s);
366 Assertions.assertEquals(value, d, () -> value + " formatted as " + s);
367 }
368
369 @Test
370 void testMixed_custom() {
371
372 final DoubleFunction<String> fmt = DoubleFormat.MIXED.builder()
373 .maxPrecision(3)
374 .minDecimalExponent(-3)
375 .allowSignedZero(false)
376 .includeFractionPlaceholder(false)
377 .decimalSeparator(',')
378 .plainFormatMaxDecimalExponent(4)
379 .plainFormatMinDecimalExponent(-1)
380 .exponentSeparator("e")
381 .infinity("inf")
382 .nan("nan")
383 .minusSign('!')
384 .get();
385
386
387 checkFormat(fmt, Double.NaN, "nan");
388 checkFormat(fmt, Double.POSITIVE_INFINITY, "inf");
389 checkFormat(fmt, Double.NEGATIVE_INFINITY, "!inf");
390
391 checkFormat(fmt, 0.00001, "0");
392 checkFormat(fmt, -0.0001, "0");
393 checkFormat(fmt, 0.001, "1e!3");
394 checkFormat(fmt, -0.01, "!1e!2");
395 checkFormat(fmt, 0.1, "0,1");
396 checkFormat(fmt, -0.0, "0");
397 checkFormat(fmt, 0.0, "0");
398 checkFormat(fmt, -1.0, "!1");
399 checkFormat(fmt, 10.0, "10");
400 checkFormat(fmt, -100.0, "!100");
401 checkFormat(fmt, 1000.0, "1000");
402 checkFormat(fmt, -10000.0, "!10000");
403 checkFormat(fmt, 100000.0, "1e5");
404 checkFormat(fmt, -1000000.0, "!1e6");
405 checkFormat(fmt, 10000000.0, "1e7");
406 checkFormat(fmt, -100000000.0, "!1e8");
407
408 checkFormat(fmt, 1.25e-3, "1e!3");
409 checkFormat(fmt, -9.975e-4, "!1e!3");
410 checkFormat(fmt, 12345, "12300");
411 checkFormat(fmt, -9_999_999, "!1e7");
412 checkFormat(fmt, 1.00001e7, "1e7");
413
414 checkFormat(fmt, Double.MAX_VALUE, "1,8e308");
415 checkFormat(fmt, Double.MIN_VALUE, "0");
416 checkFormat(fmt, Double.MIN_NORMAL, "0");
417 checkFormat(fmt, Math.PI, "3,14");
418 checkFormat(fmt, Math.E, "2,72");
419 }
420
421 @Test
422 void testMixed_defaults() {
423
424 testMixed_defaults(DoubleFormat.MIXED.builder().get());
425 }
426
427 private void testMixed_defaults(final DoubleFunction<String> fmt) {
428
429 checkDefaultFormatSpecial(fmt);
430
431 checkFormat(fmt, 0.00001, "1.0E-5");
432 checkFormat(fmt, -0.0001, "-1.0E-4");
433 checkFormat(fmt, 0.001, "0.001");
434 checkFormat(fmt, -0.01, "-0.01");
435 checkFormat(fmt, 0.1, "0.1");
436 checkFormat(fmt, -0.0, "-0.0");
437 checkFormat(fmt, 0.0, "0.0");
438 checkFormat(fmt, -1.0, "-1.0");
439 checkFormat(fmt, 10.0, "10.0");
440 checkFormat(fmt, -100.0, "-100.0");
441 checkFormat(fmt, 1000.0, "1000.0");
442 checkFormat(fmt, -10000.0, "-10000.0");
443 checkFormat(fmt, 100000.0, "100000.0");
444 checkFormat(fmt, -1000000.0, "-1000000.0");
445 checkFormat(fmt, 10000000.0, "1.0E7");
446 checkFormat(fmt, -100000000.0, "-1.0E8");
447
448 checkFormat(fmt, 1.25e-3, "0.00125");
449 checkFormat(fmt, -9.975e-4, "-9.975E-4");
450 checkFormat(fmt, 12345, "12345.0");
451 checkFormat(fmt, -9_999_999, "-9999999.0");
452 checkFormat(fmt, 1.00001e7, "1.00001E7");
453
454 checkFormat(fmt, Double.MAX_VALUE, "1.7976931348623157E308");
455 checkFormat(fmt, Double.MIN_VALUE, "4.9E-324");
456 checkFormat(fmt, Double.MIN_NORMAL, "2.2250738585072014E-308");
457 checkFormat(fmt, Math.PI, "3.141592653589793");
458 checkFormat(fmt, Math.E, "2.718281828459045");
459 }
460
461 @Test
462 void testMixed_defaultsDeprecated() {
463 testMixed_defaults(DoubleFormat.MIXED.builder().build());
464 }
465
466 @Test
467 void testPlain_custom() {
468
469 final DoubleFunction<String> fmt = DoubleFormat.PLAIN.builder()
470 .maxPrecision(3)
471 .minDecimalExponent(-3)
472 .allowSignedZero(false)
473 .includeFractionPlaceholder(false)
474 .decimalSeparator(',')
475 .exponentSeparator("e")
476 .infinity("inf")
477 .nan("nan")
478 .minusSign('!')
479 .get();
480
481
482 checkFormat(fmt, Double.NaN, "nan");
483 checkFormat(fmt, Double.POSITIVE_INFINITY, "inf");
484 checkFormat(fmt, Double.NEGATIVE_INFINITY, "!inf");
485
486 checkFormat(fmt, 0.00001, "0");
487 checkFormat(fmt, -0.0001, "0");
488 checkFormat(fmt, 0.001, "0,001");
489 checkFormat(fmt, -0.01, "!0,01");
490 checkFormat(fmt, 0.1, "0,1");
491 checkFormat(fmt, -0.0, "0");
492 checkFormat(fmt, 0.0, "0");
493 checkFormat(fmt, -1.0, "!1");
494 checkFormat(fmt, 10.0, "10");
495 checkFormat(fmt, -100.0, "!100");
496 checkFormat(fmt, 1000.0, "1000");
497 checkFormat(fmt, -10000.0, "!10000");
498 checkFormat(fmt, 100000.0, "100000");
499 checkFormat(fmt, -1000000.0, "!1000000");
500 checkFormat(fmt, 10000000.0, "10000000");
501 checkFormat(fmt, -100000000.0, "!100000000");
502
503 checkFormat(fmt, 1.25e-3, "0,001");
504 checkFormat(fmt, -9.975e-4, "!0,001");
505 checkFormat(fmt, 12345, "12300");
506 checkFormat(fmt, -9_999_999, "!10000000");
507 checkFormat(fmt, 1.00001e7, "10000000");
508
509 checkFormat(fmt, Float.MAX_VALUE, "340000000000000000000000000000000000000");
510 checkFormat(fmt, -Float.MIN_VALUE, "0");
511 checkFormat(fmt, Float.MIN_NORMAL, "0");
512 checkFormat(fmt, Math.PI, "3,14");
513 checkFormat(fmt, Math.E, "2,72");
514 }
515
516 @Test
517 void testPlain_defaults() {
518
519 final DoubleFunction<String> fmt = DoubleFormat.PLAIN.builder()
520 .get();
521
522
523 checkFormat(fmt, 0.00001, "0.00001");
524 checkFormat(fmt, -0.0001, "-0.0001");
525 checkFormat(fmt, 0.001, "0.001");
526 checkFormat(fmt, -0.01, "-0.01");
527 checkFormat(fmt, 0.1, "0.1");
528 checkFormat(fmt, -0.0, "-0.0");
529 checkFormat(fmt, 0.0, "0.0");
530 checkFormat(fmt, -1.0, "-1.0");
531 checkFormat(fmt, 10.0, "10.0");
532 checkFormat(fmt, -100.0, "-100.0");
533 checkFormat(fmt, 1000.0, "1000.0");
534 checkFormat(fmt, -10000.0, "-10000.0");
535 checkFormat(fmt, 100000.0, "100000.0");
536 checkFormat(fmt, -1000000.0, "-1000000.0");
537 checkFormat(fmt, 10000000.0, "10000000.0");
538 checkFormat(fmt, -100000000.0, "-100000000.0");
539
540 checkFormat(fmt, 1.25e-3, "0.00125");
541 checkFormat(fmt, -9.975e-4, "-0.0009975");
542 checkFormat(fmt, 12345, "12345.0");
543 checkFormat(fmt, -9_999_999, "-9999999.0");
544 checkFormat(fmt, 1.00001e7, "10000100.0");
545
546 checkFormat(fmt, Float.MAX_VALUE, "340282346638528860000000000000000000000.0");
547 checkFormat(fmt, -Float.MIN_VALUE, "-0.000000000000000000000000000000000000000000001401298464324817");
548 checkFormat(fmt, Float.MIN_NORMAL, "0.000000000000000000000000000000000000011754943508222875");
549 checkFormat(fmt, Math.PI, "3.141592653589793");
550 checkFormat(fmt, Math.E, "2.718281828459045");
551 }
552
553 @Test
554 void testPlain_localeFormatComparison() {
555
556 checkLocalizedFormats("0.0##", loc -> DoubleFormat.PLAIN.builder()
557 .minDecimalExponent(-3)
558 .formatSymbols(DecimalFormatSymbols.getInstance(loc))
559 .get());
560 checkLocalizedFormats("#,##0.0##", loc -> DoubleFormat.PLAIN.builder()
561 .minDecimalExponent(-3)
562 .groupThousands(true)
563 .formatSymbols(DecimalFormatSymbols.getInstance(loc))
564 .get());
565 }
566
567 @Test
568 void testScientific_custom() {
569
570 final DoubleFunction<String> fmt = DoubleFormat.SCIENTIFIC.builder()
571 .maxPrecision(3)
572 .minDecimalExponent(-3)
573 .allowSignedZero(false)
574 .includeFractionPlaceholder(false)
575 .decimalSeparator(',')
576 .exponentSeparator("e")
577 .infinity("inf")
578 .nan("nan")
579 .minusSign('!')
580 .get();
581
582
583 checkFormat(fmt, Double.NaN, "nan");
584 checkFormat(fmt, Double.POSITIVE_INFINITY, "inf");
585 checkFormat(fmt, Double.NEGATIVE_INFINITY, "!inf");
586
587 checkFormat(fmt, 0.00001, "0");
588 checkFormat(fmt, -0.0001, "0");
589 checkFormat(fmt, 0.001, "1e!3");
590 checkFormat(fmt, -0.01, "!1e!2");
591 checkFormat(fmt, 0.1, "1e!1");
592 checkFormat(fmt, -0.0, "0");
593 checkFormat(fmt, 0.0, "0");
594 checkFormat(fmt, -1.0, "!1");
595 checkFormat(fmt, 10.0, "1e1");
596 checkFormat(fmt, -100.0, "!1e2");
597 checkFormat(fmt, 1000.0, "1e3");
598 checkFormat(fmt, -10000.0, "!1e4");
599 checkFormat(fmt, 100000.0, "1e5");
600 checkFormat(fmt, -1000000.0, "!1e6");
601 checkFormat(fmt, 10000000.0, "1e7");
602 checkFormat(fmt, -100000000.0, "!1e8");
603
604 checkFormat(fmt, 1.25e-3, "1e!3");
605 checkFormat(fmt, -9.975e-4, "!1e!3");
606 checkFormat(fmt, 12345, "1,23e4");
607 checkFormat(fmt, -9_999_999, "!1e7");
608 checkFormat(fmt, 1.00001e7, "1e7");
609
610 checkFormat(fmt, Double.MAX_VALUE, "1,8e308");
611 checkFormat(fmt, Double.MIN_VALUE, "0");
612 checkFormat(fmt, Double.MIN_NORMAL, "0");
613 checkFormat(fmt, Math.PI, "3,14");
614 checkFormat(fmt, Math.E, "2,72");
615 }
616
617 @Test
618 void testScientific_defaults() {
619
620 final DoubleFunction<String> fmt = DoubleFormat.SCIENTIFIC.builder().get();
621
622
623 checkDefaultFormatSpecial(fmt);
624
625 checkFormat(fmt, 0.00001, "1.0E-5");
626 checkFormat(fmt, -0.0001, "-1.0E-4");
627 checkFormat(fmt, 0.001, "1.0E-3");
628 checkFormat(fmt, -0.01, "-1.0E-2");
629 checkFormat(fmt, 0.1, "1.0E-1");
630 checkFormat(fmt, -0.0, "-0.0");
631 checkFormat(fmt, 0.0, "0.0");
632 checkFormat(fmt, -1.0, "-1.0");
633 checkFormat(fmt, 10.0, "1.0E1");
634 checkFormat(fmt, -100.0, "-1.0E2");
635 checkFormat(fmt, 1000.0, "1.0E3");
636 checkFormat(fmt, -10000.0, "-1.0E4");
637 checkFormat(fmt, 100000.0, "1.0E5");
638 checkFormat(fmt, -1000000.0, "-1.0E6");
639 checkFormat(fmt, 10000000.0, "1.0E7");
640 checkFormat(fmt, -100000000.0, "-1.0E8");
641
642 checkFormat(fmt, 1.25e-3, "1.25E-3");
643 checkFormat(fmt, -9.975e-4, "-9.975E-4");
644 checkFormat(fmt, 12345, "1.2345E4");
645 checkFormat(fmt, -9_999_999, "-9.999999E6");
646 checkFormat(fmt, 1.00001e7, "1.00001E7");
647
648 checkFormat(fmt, Double.MAX_VALUE, "1.7976931348623157E308");
649 checkFormat(fmt, Double.MIN_VALUE, "4.9E-324");
650 checkFormat(fmt, Double.MIN_NORMAL, "2.2250738585072014E-308");
651 checkFormat(fmt, Math.PI, "3.141592653589793");
652 checkFormat(fmt, Math.E, "2.718281828459045");
653 }
654
655 @Test
656 void testScientific_localeFormatComparison() {
657
658 checkLocalizedFormats("0.0##E0", loc -> DoubleFormat.SCIENTIFIC.builder()
659 .maxPrecision(4)
660 .alwaysIncludeExponent(true)
661 .formatSymbols(DecimalFormatSymbols.getInstance(loc))
662 .get());
663 }
664 }