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