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.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertThrows;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.math.BigDecimal;
25 import java.math.MathContext;
26 import java.math.RoundingMode;
27 import java.util.function.BiFunction;
28
29 import org.apache.commons.rng.UniformRandomProvider;
30 import org.apache.commons.rng.simple.RandomSource;
31 import org.junit.jupiter.api.Test;
32 import org.junit.jupiter.api.function.Executable;
33
34 class ParsedDecimalTest {
35
36 private static final class FormatOptionsImpl implements ParsedDecimal.FormatOptions {
37
38 private boolean includeFractionPlaceholder = true;
39
40 private boolean signedZero = true;
41
42 private char[] digits = "0123456789".toCharArray();
43
44 private char decimalSeparator = '.';
45
46 private char thousandsGroupingSeparator = ',';
47
48 private boolean groupThousands;
49
50 private char minusSign = '-';
51
52 private String exponentSeparator = "E";
53
54 private boolean alwaysIncludeExponent;
55
56 @Override
57 public char getDecimalSeparator() {
58 return decimalSeparator;
59 }
60
61 @Override
62 public char[] getDigits() {
63 return digits;
64 }
65
66 @Override
67 public char[] getExponentSeparatorChars() {
68 return exponentSeparator.toCharArray();
69 }
70
71 @Override
72 public char getGroupingSeparator() {
73 return thousandsGroupingSeparator;
74 }
75
76 @Override
77 public char getMinusSign() {
78 return minusSign;
79 }
80
81 @Override
82 public boolean isAlwaysIncludeExponent() {
83 return alwaysIncludeExponent;
84 }
85
86 @Override
87 public boolean isGroupThousands() {
88 return groupThousands;
89 }
90
91 @Override
92 public boolean isIncludeFractionPlaceholder() {
93 return includeFractionPlaceholder;
94 }
95
96 @Override
97 public boolean isSignedZero() {
98 return signedZero;
99 }
100
101 public void setAlwaysIncludeExponent(final boolean alwaysIncludeExponent) {
102 this.alwaysIncludeExponent = alwaysIncludeExponent;
103 }
104
105 public void setDecimalSeparator(final char decimalSeparator) {
106 this.decimalSeparator = decimalSeparator;
107 }
108
109 public void setDigitsFromString(final String digits) {
110 this.digits = digits.toCharArray();
111 }
112
113 public void setExponentSeparator(final String exponentSeparator) {
114 this.exponentSeparator = exponentSeparator;
115 }
116
117 public void setGroupThousands(final boolean groupThousands) {
118 this.groupThousands = groupThousands;
119 }
120
121 public void setIncludeFractionPlaceholder(final boolean includeFractionPlaceholder) {
122 this.includeFractionPlaceholder = includeFractionPlaceholder;
123 }
124
125 public void setMinusSign(final char minusSign) {
126 this.minusSign = minusSign;
127 }
128
129 public void setSignedZero(final boolean signedZero) {
130 this.signedZero = signedZero;
131 }
132
133 public void setThousandsGroupingSeparator(final char thousandsGroupingSeparator) {
134 this.thousandsGroupingSeparator = thousandsGroupingSeparator;
135 }
136 }
137
138 private static void assertMaxPrecision(final double d, final int maxPrecision,
139 final boolean negative, final String digits, final int exponent) {
140 final ParsedDecimal dec = ParsedDecimal.from(d);
141 dec.maxPrecision(maxPrecision);
142
143 assertSimpleDecimal(dec, negative, digits, exponent);
144 }
145
146 private static void assertRound(final double d, final int roundExponent,
147 final boolean negative, final String digits, final int exponent) {
148 final ParsedDecimal dec = ParsedDecimal.from(d);
149 dec.round(roundExponent);
150
151 assertSimpleDecimal(dec, negative, digits, exponent);
152 }
153
154 private static void assertSimpleDecimal(final ParsedDecimal parsed, final boolean negative, final String digits,
155 final int exponent) {
156 assertEquals(negative, parsed.negative);
157 assertEquals(digits, digitString(parsed));
158 assertEquals(exponent, parsed.getExponent());
159 assertEquals(digits.length(), parsed.digitCount);
160 assertEquals(exponent, parsed.getScientificExponent() - digits.length() + 1);
161 }
162
163 private static void assertThrowsWithMessage(final Executable fn, final Class<? extends Throwable> type,
164 final String msg) {
165 final Throwable exc = assertThrows(type, fn);
166 assertEquals(msg, exc.getMessage());
167 }
168
169 private static void checkFrom(final double d, final String digits, final int exponent) {
170 final boolean negative = Math.signum(d) < 0;
171
172 assertSimpleDecimal(ParsedDecimal.from(d), negative, digits, exponent);
173 assertSimpleDecimal(ParsedDecimal.from(-d), !negative, digits, exponent);
174 }
175
176 private static void checkToEngineeringString(final double d, final String expected,
177 final ParsedDecimal.FormatOptions opts) {
178 checkToStringMethod(d, expected, ParsedDecimal::toEngineeringString, opts);
179
180
181 final String pos = ParsedDecimal.from(d).toEngineeringString(opts);
182 assertEquals(0, parseExponent(pos, opts) % 3);
183
184 final String neg = ParsedDecimal.from(-d).toEngineeringString(opts);
185 assertEquals(0, parseExponent(neg, opts) % 3);
186 }
187
188 private static void checkToPlainString(final double d, final String expected,
189 final ParsedDecimal.FormatOptions opts) {
190 checkToStringMethod(d, expected, ParsedDecimal::toPlainString, opts);
191 }
192
193 private static void checkToScientificString(final double d, final String expected,
194 final ParsedDecimal.FormatOptions opts) {
195 checkToStringMethod(d, expected, ParsedDecimal::toScientificString, opts);
196 }
197
198 private static void checkToStringMethod(final double d, final String expected,
199 final BiFunction<ParsedDecimal, ParsedDecimal.FormatOptions, String> fn,
200 final ParsedDecimal.FormatOptions opts) {
201
202 final ParsedDecimal pos = ParsedDecimal.from(d);
203 final String actual = fn.apply(pos, opts);
204
205 assertEquals(expected, actual);
206 }
207
208 private static double createRandomDouble(final UniformRandomProvider rng) {
209 final long mask = (1L << 52) - 1 | 1L << 63;
210 final long bits = rng.nextLong() & mask;
211 final long exp = rng.nextInt(2045) + 1;
212 return Double.longBitsToDouble(bits | exp << 52);
213 }
214
215
216
217
218
219 private static String digitString(final ParsedDecimal dec) {
220 final StringBuilder sb = new StringBuilder();
221 for (int i = 0; i < dec.digitCount; ++i) {
222 sb.append(dec.digits[i]);
223 }
224 return sb.toString();
225 }
226
227 private static int parseExponent(final String str, final ParsedDecimal.FormatOptions opts) {
228 final char[] expSep = opts.getExponentSeparatorChars();
229
230 final int expStartIdx = str.indexOf(String.valueOf(expSep));
231 if (expStartIdx > -1) {
232 int expIdx = expStartIdx + expSep.length;
233
234 boolean neg = false;
235 if (str.charAt(expIdx) == opts.getMinusSign()) {
236 ++expIdx;
237 neg = true;
238 }
239
240 final String expStr = str.substring(expIdx);
241 final int val = Integer.parseInt(expStr);
242 return neg
243 ? -val
244 : val;
245 }
246
247 return 0;
248 }
249
250 @Test
251 void testFrom() {
252
253 checkFrom(0.0, "0", 0);
254
255 checkFrom(1.0, "1", 0);
256 checkFrom(10.0, "1", 1);
257 checkFrom(100.0, "1", 2);
258 checkFrom(1000.0, "1", 3);
259 checkFrom(10000.0, "1", 4);
260
261 checkFrom(0.1, "1", -1);
262 checkFrom(0.01, "1", -2);
263 checkFrom(0.001, "1", -3);
264 checkFrom(0.0001, "1", -4);
265 checkFrom(0.00001, "1", -5);
266
267 checkFrom(1.2, "12", -1);
268 checkFrom(0.00971, "971", -5);
269 checkFrom(56300, "563", 2);
270
271 checkFrom(123.0, "123", 0);
272 checkFrom(1230.0, "123", 1);
273 checkFrom(12300.0, "123", 2);
274 checkFrom(123000.0, "123", 3);
275
276 checkFrom(12.3, "123", -1);
277 checkFrom(1.23, "123", -2);
278 checkFrom(0.123, "123", -3);
279 checkFrom(0.0123, "123", -4);
280
281 checkFrom(1.987654321e270, "1987654321", 261);
282 checkFrom(1.987654321e-270, "1987654321", -279);
283
284 checkFrom(Math.PI, "3141592653589793", -15);
285 checkFrom(Math.E, "2718281828459045", -15);
286
287 checkFrom(Double.MAX_VALUE, "17976931348623157", 292);
288 checkFrom(Double.MIN_VALUE, "49", -325);
289 checkFrom(Double.MIN_NORMAL, "22250738585072014", -324);
290 }
291
292 @Test
293 void testFromNotFinite() {
294
295 final String msg = "Double is not finite";
296
297
298 assertThrowsWithMessage(() -> ParsedDecimal.from(Double.NaN),
299 IllegalArgumentException.class, msg);
300 assertThrowsWithMessage(() -> ParsedDecimal.from(Double.NEGATIVE_INFINITY),
301 IllegalArgumentException.class, msg);
302 assertThrowsWithMessage(() -> ParsedDecimal.from(Double.POSITIVE_INFINITY),
303 IllegalArgumentException.class, msg);
304 }
305
306 @Test
307 void testIsZero() {
308
309 assertTrue(ParsedDecimal.from(0.0).isZero());
310 assertTrue(ParsedDecimal.from(-0.0).isZero());
311
312 assertFalse(ParsedDecimal.from(1.0).isZero());
313 assertFalse(ParsedDecimal.from(-1.0).isZero());
314
315 assertFalse(ParsedDecimal.from(Double.MIN_NORMAL).isZero());
316 assertFalse(ParsedDecimal.from(-Double.MIN_NORMAL).isZero());
317
318 assertFalse(ParsedDecimal.from(Double.MAX_VALUE).isZero());
319 assertFalse(ParsedDecimal.from(-Double.MIN_VALUE).isZero());
320 }
321
322 @Test
323 void testMaxPrecision() {
324
325 final double d = 1.02576552;
326
327
328 assertMaxPrecision(d, 10, false, "102576552", -8);
329 assertMaxPrecision(d, 9, false, "102576552", -8);
330 assertMaxPrecision(d, 8, false, "10257655", -7);
331 assertMaxPrecision(d, 7, false, "1025766", -6);
332 assertMaxPrecision(d, 6, false, "102577", -5);
333 assertMaxPrecision(d, 5, false, "10258", -4);
334 assertMaxPrecision(d, 4, false, "1026", -3);
335 assertMaxPrecision(d, 3, false, "103", -2);
336 assertMaxPrecision(d, 2, false, "1", 0);
337 assertMaxPrecision(d, 1, false, "1", 0);
338
339 assertMaxPrecision(d, 0, false, "102576552", -8);
340 }
341
342 @Test
343 void testMaxPrecision_carry() {
344
345 final double d = -999.0999e50;
346
347
348 assertMaxPrecision(d, 8, true, "9990999", 46);
349 assertMaxPrecision(d, 7, true, "9990999", 46);
350 assertMaxPrecision(d, 6, true, "9991", 49);
351 assertMaxPrecision(d, 5, true, "9991", 49);
352 assertMaxPrecision(d, 4, true, "9991", 49);
353 assertMaxPrecision(d, 3, true, "999", 50);
354 assertMaxPrecision(d, 2, true, "1", 53);
355 assertMaxPrecision(d, 1, true, "1", 53);
356
357 assertMaxPrecision(d, 0, true, "9990999", 46);
358 }
359
360 @Test
361 void testMaxPrecision_halfEvenRounding() {
362
363
364 assertMaxPrecision(5.5, 1, false, "6", 0);
365 assertMaxPrecision(2.5, 1, false, "2", 0);
366 assertMaxPrecision(1.6, 1, false, "2", 0);
367 assertMaxPrecision(1.1, 1, false, "1", 0);
368 assertMaxPrecision(1.0, 1, false, "1", 0);
369
370 assertMaxPrecision(-1.0, 1, true, "1", 0);
371 assertMaxPrecision(-1.1, 1, true, "1", 0);
372 assertMaxPrecision(-1.6, 1, true, "2", 0);
373 assertMaxPrecision(-2.5, 1, true, "2", 0);
374 assertMaxPrecision(-5.5, 1, true, "6", 0);
375 }
376
377 @Test
378 void testMaxPrecision_random() {
379
380 final UniformRandomProvider rand = RandomSource.XO_RO_SHI_RO_128_PP.create(0L);
381 final ParsedDecimal.FormatOptions opts = new FormatOptionsImpl();
382
383 for (int i = 0; i < 10_000; ++i) {
384 final double d = createRandomDouble(rand);
385 final int precision = rand.nextInt(20) + 1;
386 final MathContext ctx = new MathContext(precision, RoundingMode.HALF_EVEN);
387
388 final ParsedDecimal dec = ParsedDecimal.from(d);
389
390
391 dec.maxPrecision(precision);
392
393
394 assertEquals(new BigDecimal(Double.toString(d), ctx).doubleValue(),
395 Double.parseDouble(dec.toScientificString(opts)));
396 }
397 }
398
399 @Test
400 void testMaxPrecision_singleDigits() {
401
402 assertMaxPrecision(9.0, 1, false, "9", 0);
403 assertMaxPrecision(1.0, 1, false, "1", 0);
404 assertMaxPrecision(0.0, 1, false, "0", 0);
405 assertMaxPrecision(-0.0, 1, true, "0", 0);
406 assertMaxPrecision(-1.0, 1, true, "1", 0);
407 assertMaxPrecision(-9.0, 1, true, "9", 0);
408 }
409
410 @Test
411 void testRound_mixed() {
412
413 final double a = 9.94e-10;
414 final double b = -3.1415;
415 final double c = 5.55e10;
416
417
418 assertRound(a, -13, false, "994", -12);
419 assertRound(a, -12, false, "994", -12);
420 assertRound(a, -11, false, "99", -11);
421 assertRound(a, -10, false, "1", -9);
422 assertRound(a, -9, false, "1", -9);
423 assertRound(a, -8, false, "0", 0);
424
425 assertRound(b, -5, true, "31415", -4);
426 assertRound(b, -4, true, "31415", -4);
427 assertRound(b, -3, true, "3142", -3);
428 assertRound(b, -2, true, "314", -2);
429 assertRound(b, -1, true, "31", -1);
430 assertRound(b, 0, true, "3", 0);
431 assertRound(b, 1, true, "0", 0);
432 assertRound(b, 2, true, "0", 0);
433
434 assertRound(c, 7, false, "555", 8);
435 assertRound(c, 8, false, "555", 8);
436 assertRound(c, 9, false, "56", 9);
437 assertRound(c, 10, false, "6", 10);
438 assertRound(c, 11, false, "1", 11);
439 assertRound(c, 12, false, "0", 0);
440 }
441
442 @Test
443 void testRound_nine() {
444
445 final double a = 9e-10;
446 final double b = -9;
447 final double c = 9e10;
448
449
450 assertRound(a, -11, false, "9", -10);
451 assertRound(a, -10, false, "9", -10);
452 assertRound(a, -9, false, "1", -9);
453
454 assertRound(b, -1, true, "9", 0);
455 assertRound(b, 0, true, "9", 0);
456 assertRound(b, 1, true, "1", 1);
457
458 assertRound(c, 9, false, "9", 10);
459 assertRound(c, 10, false, "9", 10);
460 assertRound(c, 11, false, "1", 11);
461 }
462
463 @Test
464 void testRound_one() {
465
466 final double a = 1e-10;
467 final double b = -1;
468 final double c = 1e10;
469
470
471 assertRound(a, -11, false, "1", -10);
472 assertRound(a, -10, false, "1", -10);
473 assertRound(a, -9, false, "0", 0);
474
475 assertRound(b, -1, true, "1", 0);
476 assertRound(b, 0, true, "1", 0);
477 assertRound(b, 1, true, "0", 0);
478
479 assertRound(c, 9, false, "1", 10);
480 assertRound(c, 10, false, "1", 10);
481 assertRound(c, 11, false, "0", 0);
482 }
483
484 @Test
485 void testStringMethodAccuracy_random() {
486
487 final UniformRandomProvider rand = RandomSource.XO_RO_SHI_RO_128_PP.create(0L);
488
489 final FormatOptionsImpl stdOpts = new FormatOptionsImpl();
490 final FormatOptionsImpl altOpts = new FormatOptionsImpl();
491 altOpts.setExponentSeparator("e");
492 altOpts.setIncludeFractionPlaceholder(false);
493
494 double d;
495 for (int i = 0; i < 10_000; ++i) {
496 d = createRandomDouble(rand);
497
498
499 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toScientificString(stdOpts)));
500 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toScientificString(altOpts)));
501
502 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toEngineeringString(stdOpts)));
503 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toEngineeringString(altOpts)));
504
505 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toPlainString(stdOpts)));
506 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toPlainString(altOpts)));
507 }
508 }
509
510 @Test
511 void testStringMethodAccuracy_sequence() {
512
513 final double min = -1000;
514 final double max = 1000;
515 final double delta = 0.1;
516
517 final FormatOptionsImpl stdOpts = new FormatOptionsImpl();
518 final FormatOptionsImpl altOpts = new FormatOptionsImpl();
519 altOpts.setExponentSeparator("e");
520 altOpts.setIncludeFractionPlaceholder(false);
521
522 assertEquals(10.0, Double.parseDouble(ParsedDecimal.from(10.0).toScientificString(stdOpts)));
523
524 for (double d = min; d <= max; d += delta) {
525
526 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toScientificString(stdOpts)));
527 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toScientificString(altOpts)));
528
529 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toEngineeringString(stdOpts)));
530 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toEngineeringString(altOpts)));
531
532 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toPlainString(stdOpts)));
533 assertEquals(d, Double.parseDouble(ParsedDecimal.from(d).toPlainString(altOpts)));
534 }
535 }
536
537 @Test
538 void testStringMethods_customDigits() {
539
540 final FormatOptionsImpl opts = new FormatOptionsImpl();
541 opts.setDigitsFromString("abcdefghij");
542
543
544 assertEquals("b.a", ParsedDecimal.from(1.0).toPlainString(opts));
545 assertEquals("-a.abcd", ParsedDecimal.from(-0.0123).toPlainString(opts));
546 assertEquals("bc.de", ParsedDecimal.from(12.34).toPlainString(opts));
547 assertEquals("baaaa.a", ParsedDecimal.from(10000).toPlainString(opts));
548 assertEquals("jihgfedcba.a", ParsedDecimal.from(9876543210d).toPlainString(opts));
549
550 assertEquals("b.a", ParsedDecimal.from(1.0).toScientificString(opts));
551 assertEquals("-b.cdE-c", ParsedDecimal.from(-0.0123).toScientificString(opts));
552 assertEquals("b.cdeEb", ParsedDecimal.from(12.34).toScientificString(opts));
553 assertEquals("b.aEe", ParsedDecimal.from(10000).toScientificString(opts));
554 assertEquals("j.ihgfedcbEj", ParsedDecimal.from(9876543210d).toScientificString(opts));
555
556 assertEquals("b.a", ParsedDecimal.from(1.0).toEngineeringString(opts));
557 assertEquals("-bc.dE-d", ParsedDecimal.from(-0.0123).toEngineeringString(opts));
558 assertEquals("bc.de", ParsedDecimal.from(12.34).toEngineeringString(opts));
559 assertEquals("ba.aEd", ParsedDecimal.from(10000).toEngineeringString(opts));
560 assertEquals("j.ihgfedcbEj", ParsedDecimal.from(9876543210d).toEngineeringString(opts));
561 }
562
563 @Test
564 void testToEngineeringString_altFormat() {
565
566 final FormatOptionsImpl opts = new FormatOptionsImpl();
567 opts.setIncludeFractionPlaceholder(false);
568 opts.setSignedZero(false);
569 opts.setDecimalSeparator(',');
570 opts.setMinusSign('!');
571 opts.setExponentSeparator("x10^");
572 opts.setAlwaysIncludeExponent(true);
573
574
575 checkToEngineeringString(0.0, "0x10^0", opts);
576 checkToEngineeringString(-0.0, "0x10^0", opts);
577 checkToEngineeringString(1.0, "1x10^0", opts);
578 checkToEngineeringString(1.5, "1,5x10^0", opts);
579
580 checkToEngineeringString(10, "10x10^0", opts);
581
582 checkToEngineeringString(-0.000000123, "!123x10^!9", opts);
583 checkToEngineeringString(12300000, "12,3x10^6", opts);
584
585 checkToEngineeringString(Math.PI, "3,141592653589793x10^0", opts);
586 checkToEngineeringString(Math.E, "2,718281828459045x10^0", opts);
587
588 checkToEngineeringString(-Double.MAX_VALUE, "!179,76931348623157x10^306", opts);
589 checkToEngineeringString(Double.MIN_VALUE, "4,9x10^!324", opts);
590 checkToEngineeringString(Double.MIN_NORMAL, "22,250738585072014x10^!309", opts);
591 }
592
593 @Test
594 void testToEngineeringString_defaults() {
595
596 final FormatOptionsImpl opts = new FormatOptionsImpl();
597
598
599 checkToEngineeringString(0.0, "0.0", opts);
600 checkToEngineeringString(-0.0, "-0.0", opts);
601 checkToEngineeringString(1.0, "1.0", opts);
602 checkToEngineeringString(1.5, "1.5", opts);
603
604 checkToEngineeringString(10, "10.0", opts);
605
606 checkToEngineeringString(-0.000000123, "-123.0E-9", opts);
607 checkToEngineeringString(12300000, "12.3E6", opts);
608
609 checkToEngineeringString(Math.PI, "3.141592653589793", opts);
610 checkToEngineeringString(Math.E, "2.718281828459045", opts);
611
612 checkToEngineeringString(-Double.MAX_VALUE, "-179.76931348623157E306", opts);
613 checkToEngineeringString(Double.MIN_VALUE, "4.9E-324", opts);
614 checkToEngineeringString(Double.MIN_NORMAL, "22.250738585072014E-309", opts);
615 }
616
617 @Test
618 void testToPlainString_altFormat() {
619
620 final FormatOptionsImpl opts = new FormatOptionsImpl();
621 opts.setIncludeFractionPlaceholder(false);
622 opts.setSignedZero(false);
623 opts.setDecimalSeparator(',');
624 opts.setMinusSign('!');
625 opts.setThousandsGroupingSeparator('_');
626 opts.setGroupThousands(true);
627
628
629 checkToPlainString(0.0, "0", opts);
630 checkToPlainString(-0.0, "0", opts);
631 checkToPlainString(1.0, "1", opts);
632 checkToPlainString(1.5, "1,5", opts);
633
634 checkToPlainString(12, "12", opts);
635 checkToPlainString(123, "123", opts);
636 checkToPlainString(1234, "1_234", opts);
637 checkToPlainString(12345, "12_345", opts);
638 checkToPlainString(123456, "123_456", opts);
639 checkToPlainString(1234567, "1_234_567", opts);
640 checkToPlainString(12345678, "12_345_678", opts);
641 checkToPlainString(123456789, "123_456_789", opts);
642 checkToPlainString(1234567890, "1_234_567_890", opts);
643
644 checkToPlainString(-0.000123, "!0,000123", opts);
645 checkToPlainString(12301, "12_301", opts);
646
647 checkToPlainString(Math.PI, "3,141592653589793", opts);
648 checkToPlainString(Math.E, "2,718281828459045", opts);
649
650 checkToPlainString(-12345.6789, "!12_345,6789", opts);
651 checkToPlainString(1.23e12, "1_230_000_000_000", opts);
652 checkToPlainString(1.23e-12, "0,00000000000123", opts);
653 }
654
655 @Test
656 void testToPlainString_defaults() {
657
658 final FormatOptionsImpl opts = new FormatOptionsImpl();
659
660
661 checkToPlainString(0.0, "0.0", opts);
662 checkToPlainString(-0.0, "-0.0", opts);
663 checkToPlainString(1.0, "1.0", opts);
664 checkToPlainString(1.5, "1.5", opts);
665
666 checkToPlainString(12, "12.0", opts);
667 checkToPlainString(123, "123.0", opts);
668 checkToPlainString(1234, "1234.0", opts);
669 checkToPlainString(12345, "12345.0", opts);
670 checkToPlainString(123456, "123456.0", opts);
671 checkToPlainString(1234567, "1234567.0", opts);
672 checkToPlainString(12345678, "12345678.0", opts);
673 checkToPlainString(123456789, "123456789.0", opts);
674 checkToPlainString(1234567890, "1234567890.0", opts);
675
676 checkToPlainString(-0.000123, "-0.000123", opts);
677 checkToPlainString(12301, "12301.0", opts);
678
679 checkToPlainString(Math.PI, "3.141592653589793", opts);
680 checkToPlainString(Math.E, "2.718281828459045", opts);
681
682 checkToPlainString(-12345.6789, "-12345.6789", opts);
683 checkToPlainString(1.23e12, "1230000000000.0", opts);
684 checkToPlainString(1.23e-12, "0.00000000000123", opts);
685 }
686
687 @Test
688 void testToScientificString_altFormats() {
689
690 final FormatOptionsImpl opts = new FormatOptionsImpl();
691 opts.setIncludeFractionPlaceholder(false);
692 opts.setSignedZero(false);
693 opts.setDecimalSeparator(',');
694 opts.setMinusSign('!');
695 opts.setExponentSeparator("x10^");
696 opts.setAlwaysIncludeExponent(true);
697
698
699 checkToScientificString(0.0, "0x10^0", opts);
700 checkToScientificString(-0.0, "0x10^0", opts);
701 checkToScientificString(1.0, "1x10^0", opts);
702 checkToScientificString(1.5, "1,5x10^0", opts);
703
704 checkToScientificString(-0.000123, "!1,23x10^!4", opts);
705 checkToScientificString(12301, "1,2301x10^4", opts);
706
707 checkToScientificString(Math.PI, "3,141592653589793x10^0", opts);
708 checkToScientificString(Math.E, "2,718281828459045x10^0", opts);
709
710 checkToScientificString(-Double.MAX_VALUE, "!1,7976931348623157x10^308", opts);
711 checkToScientificString(Double.MIN_VALUE, "4,9x10^!324", opts);
712 checkToScientificString(Double.MIN_NORMAL, "2,2250738585072014x10^!308", opts);
713 }
714
715 @Test
716 void testToScientificString_defaults() {
717
718 final FormatOptionsImpl opts = new FormatOptionsImpl();
719
720
721 checkToScientificString(0.0, "0.0", opts);
722 checkToScientificString(-0.0, "-0.0", opts);
723 checkToScientificString(1.0, "1.0", opts);
724 checkToScientificString(1.5, "1.5", opts);
725
726 checkToScientificString(-0.000123, "-1.23E-4", opts);
727 checkToScientificString(12301, "1.2301E4", opts);
728
729 checkToScientificString(Math.PI, "3.141592653589793", opts);
730 checkToScientificString(Math.E, "2.718281828459045", opts);
731
732 checkToScientificString(-Double.MAX_VALUE, "-1.7976931348623157E308", opts);
733 checkToScientificString(Double.MIN_VALUE, "4.9E-324", opts);
734 checkToScientificString(Double.MIN_NORMAL, "2.2250738585072014E-308", opts);
735 }
736 }