Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
Format | 37 | 285 | 149 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
7 | * Jalview is free software: you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation, either version 3 | |
10 | * of the License, or (at your option) any later version. | |
11 | * | |
12 | * Jalview is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
15 | * PURPOSE. See the GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with Jalview. If not, see <http://www.gnu.org/licenses/>. | |
19 | * The Jalview Authors are detailed in the 'AUTHORS' file. | |
20 | */ | |
21 | /** | |
22 | * A class for formatting numbers that follows printf conventions. | |
23 | * Also implements C-like atoi and atof functions | |
24 | * @version 1.03 25 Oct 1997 | |
25 | * @author Cay Horstmann | |
26 | */ | |
27 | package jalview.util; | |
28 | ||
29 | import java.util.Arrays; | |
30 | ||
31 | /** | |
32 | * DOCUMENT ME! | |
33 | * | |
34 | * @author $author$ | |
35 | * @version $Revision$ | |
36 | */ | |
37 | public class Format | |
38 | { | |
39 | private int width; | |
40 | ||
41 | private int precision; | |
42 | ||
43 | private String pre; | |
44 | ||
45 | private String post; | |
46 | ||
47 | private boolean leading_zeroes; | |
48 | ||
49 | private boolean show_plus; | |
50 | ||
51 | private boolean alternate; | |
52 | ||
53 | private boolean show_space; | |
54 | ||
55 | private boolean left_align; | |
56 | ||
57 | private char fmt; // one of cdeEfgGiosxXos | |
58 | ||
59 | private final String formatString; | |
60 | ||
61 | /** | |
62 | * Creates a new Format object. | |
63 | * | |
64 | * @param s | |
65 | * DOCUMENT ME! | |
66 | */ | |
67 | 42786 | public Format(String s) |
68 | { | |
69 | 42786 | formatString = s; |
70 | 42786 | width = 0; |
71 | 42786 | precision = -1; |
72 | 42786 | pre = ""; |
73 | 42786 | post = ""; |
74 | 42786 | leading_zeroes = false; |
75 | 42786 | show_plus = false; |
76 | 42786 | alternate = false; |
77 | 42786 | show_space = false; |
78 | 42786 | left_align = false; |
79 | 42786 | fmt = ' '; |
80 | ||
81 | 42786 | int length = s.length(); |
82 | 42786 | int parse_state = 0; |
83 | ||
84 | // 0 = prefix, 1 = flags, 2 = width, 3 = precision, | |
85 | // 4 = format, 5 = end | |
86 | 42786 | int i = 0; |
87 | ||
88 | 88708 | while (parse_state == 0) |
89 | { | |
90 | 45922 | if (i >= length) |
91 | { | |
92 | 0 | parse_state = 5; |
93 | } | |
94 | 45922 | else if (s.charAt(i) == '%') |
95 | { | |
96 | 42786 | if (i < (length - 1)) |
97 | { | |
98 | 42786 | if (s.charAt(i + 1) == '%') |
99 | { | |
100 | 0 | pre = pre + '%'; |
101 | 0 | i++; |
102 | } | |
103 | else | |
104 | { | |
105 | 42786 | parse_state = 1; |
106 | } | |
107 | } | |
108 | else | |
109 | { | |
110 | 0 | throw new java.lang.IllegalArgumentException(); |
111 | } | |
112 | } | |
113 | else | |
114 | { | |
115 | 3136 | pre = pre + s.charAt(i); |
116 | } | |
117 | ||
118 | 45922 | i++; |
119 | } | |
120 | ||
121 | 86953 | while (parse_state == 1) |
122 | { | |
123 | 44167 | if (i >= length) |
124 | { | |
125 | 0 | parse_state = 5; |
126 | } | |
127 | 44167 | else if (s.charAt(i) == ' ') |
128 | { | |
129 | 0 | show_space = true; |
130 | } | |
131 | 44167 | else if (s.charAt(i) == '-') |
132 | { | |
133 | 1381 | left_align = true; |
134 | } | |
135 | 42786 | else if (s.charAt(i) == '+') |
136 | { | |
137 | 0 | show_plus = true; |
138 | } | |
139 | 42786 | else if (s.charAt(i) == '0') |
140 | { | |
141 | 0 | leading_zeroes = true; |
142 | } | |
143 | 42786 | else if (s.charAt(i) == '#') |
144 | { | |
145 | 0 | alternate = true; |
146 | } | |
147 | else | |
148 | { | |
149 | 42786 | parse_state = 2; |
150 | 42786 | i--; |
151 | } | |
152 | ||
153 | 44167 | i++; |
154 | } | |
155 | ||
156 | 129934 | while (parse_state == 2) |
157 | { | |
158 | 87148 | if (i >= length) |
159 | { | |
160 | 0 | parse_state = 5; |
161 | } | |
162 | 87148 | else if (('0' <= s.charAt(i)) && (s.charAt(i) <= '9')) |
163 | { | |
164 | 44362 | width = ((width * 10) + s.charAt(i)) - '0'; |
165 | 44362 | i++; |
166 | } | |
167 | 42786 | else if (s.charAt(i) == '.') |
168 | { | |
169 | 254 | parse_state = 3; |
170 | 254 | precision = 0; |
171 | 254 | i++; |
172 | } | |
173 | else | |
174 | { | |
175 | 42532 | parse_state = 4; |
176 | } | |
177 | } | |
178 | ||
179 | 43294 | while (parse_state == 3) |
180 | { | |
181 | 508 | if (i >= length) |
182 | { | |
183 | 0 | parse_state = 5; |
184 | } | |
185 | 508 | else if (('0' <= s.charAt(i)) && (s.charAt(i) <= '9')) |
186 | { | |
187 | 254 | precision = ((precision * 10) + s.charAt(i)) - '0'; |
188 | 254 | i++; |
189 | } | |
190 | else | |
191 | { | |
192 | 254 | parse_state = 4; |
193 | } | |
194 | } | |
195 | ||
196 | 42786 | if (parse_state == 4) |
197 | { | |
198 | 42786 | if (i >= length) |
199 | { | |
200 | 0 | parse_state = 5; |
201 | } | |
202 | else | |
203 | { | |
204 | 42786 | fmt = s.charAt(i); |
205 | } | |
206 | ||
207 | 42786 | i++; |
208 | } | |
209 | ||
210 | 42786 | if (i < length) |
211 | { | |
212 | 196 | post = s.substring(i, length); |
213 | } | |
214 | } | |
215 | ||
216 | /** | |
217 | * Formats the number following printf conventions. Main limitation: Can only | |
218 | * handle one format parameter at a time Use multiple Format objects to format | |
219 | * more than one number | |
220 | * | |
221 | * @param s | |
222 | * the format string following printf conventions The string has a | |
223 | * prefix, a format code and a suffix. The prefix and suffix become | |
224 | * part of the formatted output. The format code directs the | |
225 | * formatting of the (single) parameter to be formatted. The code has | |
226 | * the following structure | |
227 | * <ul> | |
228 | * <li>a % (required) | |
229 | * <li>a modifier (optional) | |
230 | * <dl> | |
231 | * <dt>+ | |
232 | * <dd>forces display of + for positive numbers | |
233 | * <dt>0 | |
234 | * <dd>show leading zeroes | |
235 | * <dt>- | |
236 | * <dd>align left in the field | |
237 | * <dt>space | |
238 | * <dd>prepend a space in front of positive numbers | |
239 | * <dt># | |
240 | * <dd>use "alternate" format. Add 0 or 0x for octal or hexadecimal | |
241 | * numbers. Don't suppress trailing zeroes in general floating point | |
242 | * format. | |
243 | * </dl> | |
244 | * <li>an integer denoting field width (optional) | |
245 | * <li>a period followed by an integer denoting precision (optional) | |
246 | * <li>a format descriptor (required) | |
247 | * <dl> | |
248 | * <dt>f | |
249 | * <dd>floating point number in fixed format | |
250 | * <dt>e, E | |
251 | * <dd>floating point number in exponential notation (scientific | |
252 | * format). The E format results in an uppercase E for the exponent | |
253 | * (1.14130E+003), the e format in a lowercase e. | |
254 | * <dt>g, G | |
255 | * <dd>floating point number in general format (fixed format for | |
256 | * small numbers, exponential format for large numbers). Trailing | |
257 | * zeroes are suppressed. The G format results in an uppercase E for | |
258 | * the exponent (if any), the g format in a lowercase e. | |
259 | * <dt>d, i | |
260 | * <dd>integer in decimal | |
261 | * <dt>x | |
262 | * <dd>integer in hexadecimal | |
263 | * <dt>o | |
264 | * <dd>integer in octal | |
265 | * <dt>s | |
266 | * <dd>string | |
267 | * <dt>c | |
268 | * <dd>character | |
269 | * </dl> | |
270 | * </ul> | |
271 | * @exception IllegalArgumentException | |
272 | * if bad format | |
273 | * | |
274 | */ | |
275 | 9013 | public static String getHexString(java.awt.Color color) |
276 | { | |
277 | 9013 | String r; |
278 | 9013 | String g; |
279 | 9013 | String b; |
280 | 9013 | r = Integer.toHexString(color.getRed()); |
281 | ||
282 | 9013 | if (r.length() < 2) |
283 | { | |
284 | 67 | r = "0" + r; |
285 | } | |
286 | ||
287 | 9013 | g = Integer.toHexString(color.getGreen()); |
288 | ||
289 | 9013 | if (g.length() < 2) |
290 | { | |
291 | 262 | g = "0" + g; |
292 | } | |
293 | ||
294 | 9013 | b = Integer.toHexString(color.getBlue()); |
295 | ||
296 | 9013 | if (b.length() < 2) |
297 | { | |
298 | 800 | b = "0" + b; |
299 | } | |
300 | ||
301 | 9013 | return r + g + b; |
302 | } | |
303 | ||
304 | /** | |
305 | * prints a formatted number following printf conventions | |
306 | * | |
307 | * @param s | |
308 | * a PrintStream | |
309 | * @param fmt | |
310 | * the format string | |
311 | * @param x | |
312 | * the double to print | |
313 | */ | |
314 | 0 | public static void print(java.io.PrintStream s, String fmt, double x) |
315 | { | |
316 | 0 | s.print(new Format(fmt).form(x)); |
317 | } | |
318 | ||
319 | /** | |
320 | * prints a formatted number following printf conventions | |
321 | * | |
322 | * @param s | |
323 | * a PrintStream | |
324 | * @param fmt | |
325 | * the format string | |
326 | * @param x | |
327 | * the long to print | |
328 | */ | |
329 | 0 | public static void print(java.io.PrintStream s, String fmt, long x) |
330 | { | |
331 | 0 | s.print(new Format(fmt).form(x)); |
332 | } | |
333 | ||
334 | /** | |
335 | * prints a formatted number following printf conventions | |
336 | * | |
337 | * @param s | |
338 | * a PrintStream | |
339 | * @param fmt | |
340 | * the format string | |
341 | * @param x | |
342 | * the character to | |
343 | */ | |
344 | 0 | public static void print(java.io.PrintStream s, String fmt, char x) |
345 | { | |
346 | 0 | s.print(new Format(fmt).form(x)); |
347 | } | |
348 | ||
349 | /** | |
350 | * prints a formatted number following printf conventions | |
351 | * | |
352 | * @param s | |
353 | * a PrintStream, fmt the format string | |
354 | * @param x | |
355 | * a string that represents the digits to print | |
356 | */ | |
357 | 0 | public static void print(java.io.PrintStream s, String fmt, String x) |
358 | { | |
359 | 0 | s.print(new Format(fmt).form(x)); |
360 | } | |
361 | ||
362 | /** | |
363 | * Converts a string of digits (decimal, octal or hex) to an integer | |
364 | * | |
365 | * @param s | |
366 | * a string | |
367 | * @return the numeric value of the prefix of s representing a base 10 integer | |
368 | */ | |
369 | 0 | public static int atoi(String s) |
370 | { | |
371 | 0 | return (int) atol(s); |
372 | } | |
373 | ||
374 | /** | |
375 | * Converts a string of digits (decimal, octal or hex) to a long integer | |
376 | * | |
377 | * @param s | |
378 | * a string | |
379 | * @return the numeric value of the prefix of s representing a base 10 integer | |
380 | */ | |
381 | 0 | public static long atol(String s) |
382 | { | |
383 | 0 | int i = 0; |
384 | ||
385 | 0 | while ((i < s.length()) && Character.isWhitespace(s.charAt(i))) |
386 | { | |
387 | 0 | i++; |
388 | } | |
389 | ||
390 | 0 | if ((i < s.length()) && (s.charAt(i) == '0')) |
391 | { | |
392 | 0 | if (((i + 1) < s.length()) |
393 | && ((s.charAt(i + 1) == 'x') || (s.charAt(i + 1) == 'X'))) | |
394 | { | |
395 | 0 | return parseLong(s.substring(i + 2), 16); |
396 | } | |
397 | else | |
398 | { | |
399 | 0 | return parseLong(s, 8); |
400 | } | |
401 | } | |
402 | else | |
403 | { | |
404 | 0 | return parseLong(s, 10); |
405 | } | |
406 | } | |
407 | ||
408 | /** | |
409 | * DOCUMENT ME! | |
410 | * | |
411 | * @param s | |
412 | * DOCUMENT ME! | |
413 | * @param base | |
414 | * DOCUMENT ME! | |
415 | * | |
416 | * @return DOCUMENT ME! | |
417 | */ | |
418 | 0 | private static long parseLong(String s, int base) |
419 | { | |
420 | 0 | int i = 0; |
421 | 0 | int sign = 1; |
422 | 0 | long r = 0; |
423 | ||
424 | 0 | while ((i < s.length()) && Character.isWhitespace(s.charAt(i))) |
425 | { | |
426 | 0 | i++; |
427 | } | |
428 | ||
429 | 0 | if ((i < s.length()) && (s.charAt(i) == '-')) |
430 | { | |
431 | 0 | sign = -1; |
432 | 0 | i++; |
433 | } | |
434 | 0 | else if ((i < s.length()) && (s.charAt(i) == '+')) |
435 | { | |
436 | 0 | i++; |
437 | } | |
438 | ||
439 | 0 | while (i < s.length()) |
440 | { | |
441 | 0 | char ch = s.charAt(i); |
442 | ||
443 | 0 | if (('0' <= ch) && (ch < ('0' + base))) |
444 | { | |
445 | 0 | r = ((r * base) + ch) - '0'; |
446 | } | |
447 | 0 | else if (('A' <= ch) && (ch < (('A' + base) - 10))) |
448 | { | |
449 | 0 | r = ((r * base) + ch) - 'A' + 10; |
450 | } | |
451 | 0 | else if (('a' <= ch) && (ch < (('a' + base) - 10))) |
452 | { | |
453 | 0 | r = ((r * base) + ch) - 'a' + 10; |
454 | } | |
455 | else | |
456 | { | |
457 | 0 | return r * sign; |
458 | } | |
459 | ||
460 | 0 | i++; |
461 | } | |
462 | ||
463 | 0 | return r * sign; |
464 | } | |
465 | ||
466 | /** | |
467 | * Converts a string of digits to an double | |
468 | * | |
469 | * @param s | |
470 | * a string | |
471 | */ | |
472 | 0 | public static double atof(String s) |
473 | { | |
474 | 0 | int i = 0; |
475 | 0 | int sign = 1; |
476 | 0 | double r = 0; // integer part |
477 | // double f = 0; // fractional part | |
478 | 0 | double p = 1; // exponent of fractional part |
479 | 0 | int state = 0; // 0 = int part, 1 = frac part |
480 | ||
481 | 0 | while ((i < s.length()) && Character.isWhitespace(s.charAt(i))) |
482 | { | |
483 | 0 | i++; |
484 | } | |
485 | ||
486 | 0 | if ((i < s.length()) && (s.charAt(i) == '-')) |
487 | { | |
488 | 0 | sign = -1; |
489 | 0 | i++; |
490 | } | |
491 | 0 | else if ((i < s.length()) && (s.charAt(i) == '+')) |
492 | { | |
493 | 0 | i++; |
494 | } | |
495 | ||
496 | 0 | while (i < s.length()) |
497 | { | |
498 | 0 | char ch = s.charAt(i); |
499 | ||
500 | 0 | if (('0' <= ch) && (ch <= '9')) |
501 | { | |
502 | 0 | if (state == 0) |
503 | { | |
504 | 0 | r = ((r * 10) + ch) - '0'; |
505 | } | |
506 | 0 | else if (state == 1) |
507 | { | |
508 | 0 | p = p / 10; |
509 | 0 | r = r + (p * (ch - '0')); |
510 | } | |
511 | } | |
512 | 0 | else if (ch == '.') |
513 | { | |
514 | 0 | if (state == 0) |
515 | { | |
516 | 0 | state = 1; |
517 | } | |
518 | else | |
519 | { | |
520 | 0 | return sign * r; |
521 | } | |
522 | } | |
523 | 0 | else if ((ch == 'e') || (ch == 'E')) |
524 | { | |
525 | 0 | long e = (int) parseLong(s.substring(i + 1), 10); |
526 | ||
527 | 0 | return sign * r * Math.pow(10, e); |
528 | } | |
529 | else | |
530 | { | |
531 | 0 | return sign * r; |
532 | } | |
533 | ||
534 | 0 | i++; |
535 | } | |
536 | ||
537 | 0 | return sign * r; |
538 | } | |
539 | ||
540 | /** | |
541 | * Formats a double into a string (like sprintf in C) | |
542 | * | |
543 | * @param x | |
544 | * the number to format | |
545 | * @return the formatted string | |
546 | * @exception IllegalArgumentException | |
547 | * if bad argument | |
548 | */ | |
549 | 144590 | public String form(double x) |
550 | { | |
551 | 144591 | String r; |
552 | ||
553 | 144595 | if (precision < 0) |
554 | { | |
555 | 0 | precision = 6; |
556 | } | |
557 | ||
558 | 144593 | int s = 1; |
559 | ||
560 | 144595 | if (x < 0) |
561 | { | |
562 | 0 | x = -x; |
563 | 0 | s = -1; |
564 | } | |
565 | ||
566 | 144595 | if (fmt == 'f') |
567 | { | |
568 | 144593 | r = fixed_format(x); |
569 | } | |
570 | 3 | else if ((fmt == 'e') || (fmt == 'E') || (fmt == 'g') || (fmt == 'G')) |
571 | { | |
572 | 3 | r = exp_format(x); |
573 | } | |
574 | else | |
575 | { | |
576 | 0 | throw new java.lang.IllegalArgumentException(); |
577 | } | |
578 | ||
579 | 144594 | return pad(sign(s, r)); |
580 | } | |
581 | ||
582 | /** | |
583 | * Formats a long integer into a string (like sprintf in C) | |
584 | * | |
585 | * @param x | |
586 | * the number to format | |
587 | * @return the formatted string | |
588 | */ | |
589 | 41039 | public String form(long x) |
590 | { | |
591 | 41039 | String r; |
592 | 41039 | int s = 0; |
593 | ||
594 | 41039 | if ((fmt == 'd') || (fmt == 'i')) |
595 | { | |
596 | 41039 | if (x < 0) |
597 | { | |
598 | 0 | r = ("" + x).substring(1); |
599 | 0 | s = -1; |
600 | } | |
601 | else | |
602 | { | |
603 | 41039 | r = "" + x; |
604 | 41039 | s = 1; |
605 | } | |
606 | } | |
607 | 0 | else if (fmt == 'o') |
608 | { | |
609 | 0 | r = convert(x, 3, 7, "01234567"); |
610 | } | |
611 | 0 | else if (fmt == 'x') |
612 | { | |
613 | 0 | r = convert(x, 4, 15, "0123456789abcdef"); |
614 | } | |
615 | 0 | else if (fmt == 'X') |
616 | { | |
617 | 0 | r = convert(x, 4, 15, "0123456789ABCDEF"); |
618 | } | |
619 | else | |
620 | { | |
621 | 0 | throw new java.lang.IllegalArgumentException(); |
622 | } | |
623 | ||
624 | 41039 | return pad(sign(s, r)); |
625 | } | |
626 | ||
627 | /** | |
628 | * Formats a character into a string (like sprintf in C) | |
629 | * | |
630 | * @param debounceTrap | |
631 | * the value to format | |
632 | * @return the formatted string | |
633 | */ | |
634 | 0 | public String form(char c) |
635 | { | |
636 | 0 | if (fmt != 'c') |
637 | { | |
638 | 0 | throw new java.lang.IllegalArgumentException(); |
639 | } | |
640 | ||
641 | 0 | String r = "" + c; |
642 | ||
643 | 0 | return pad(r); |
644 | } | |
645 | ||
646 | /** | |
647 | * Formats a string into a larger string (like sprintf in C) | |
648 | * | |
649 | * @param debounceTrap | |
650 | * the value to format | |
651 | * @return the formatted string | |
652 | */ | |
653 | 3321 | public String form(String s) |
654 | { | |
655 | 3321 | if (fmt != 's') |
656 | { | |
657 | 0 | throw new java.lang.IllegalArgumentException(); |
658 | } | |
659 | ||
660 | 3321 | if (precision >= 0) |
661 | { | |
662 | 0 | s = s.substring(0, precision); |
663 | } | |
664 | ||
665 | 3321 | return pad(s); |
666 | } | |
667 | ||
668 | /** | |
669 | * Returns a string consisting of n repeats of character c | |
670 | * | |
671 | * @param c | |
672 | * @param n | |
673 | * | |
674 | * @return | |
675 | */ | |
676 | 374560 | static String repeat(char c, int n) |
677 | { | |
678 | 374568 | if (n <= 0) |
679 | { | |
680 | 331411 | return ""; |
681 | } | |
682 | 43161 | char[] chars = new char[n]; |
683 | 43161 | Arrays.fill(chars, c); |
684 | 43161 | return new String(chars); |
685 | } | |
686 | ||
687 | /** | |
688 | * DOCUMENT ME! | |
689 | * | |
690 | * @param x | |
691 | * DOCUMENT ME! | |
692 | * @param n | |
693 | * DOCUMENT ME! | |
694 | * @param m | |
695 | * DOCUMENT ME! | |
696 | * @param d | |
697 | * DOCUMENT ME! | |
698 | * | |
699 | * @return DOCUMENT ME! | |
700 | */ | |
701 | 0 | private static String convert(long x, int n, int m, String d) |
702 | { | |
703 | 0 | if (x == 0) |
704 | { | |
705 | 0 | return "0"; |
706 | } | |
707 | ||
708 | 0 | String r = ""; |
709 | ||
710 | 0 | while (x != 0) |
711 | { | |
712 | 0 | r = d.charAt((int) (x & m)) + r; |
713 | 0 | x = x >>> n; |
714 | } | |
715 | ||
716 | 0 | return r; |
717 | } | |
718 | ||
719 | /** | |
720 | * DOCUMENT ME! | |
721 | * | |
722 | * @param r | |
723 | * DOCUMENT ME! | |
724 | * | |
725 | * @return DOCUMENT ME! | |
726 | */ | |
727 | 188954 | private String pad(String r) |
728 | { | |
729 | 188954 | String p = repeat(' ', width - r.length()); |
730 | ||
731 | 188955 | if (left_align) |
732 | { | |
733 | 1423 | return pre + r + p + post; |
734 | } | |
735 | else | |
736 | { | |
737 | 187532 | return pre + p + r + post; |
738 | } | |
739 | } | |
740 | ||
741 | /** | |
742 | * DOCUMENT ME! | |
743 | * | |
744 | * @param s | |
745 | * DOCUMENT ME! | |
746 | * @param r | |
747 | * DOCUMENT ME! | |
748 | * | |
749 | * @return DOCUMENT ME! | |
750 | */ | |
751 | 185632 | private String sign(int s, String r) |
752 | { | |
753 | 185632 | String p = ""; |
754 | ||
755 | 185635 | if (s < 0) |
756 | { | |
757 | 0 | p = "-"; |
758 | } | |
759 | 185636 | else if (s > 0) |
760 | { | |
761 | 185635 | if (show_plus) |
762 | { | |
763 | 0 | p = "+"; |
764 | } | |
765 | 185635 | else if (show_space) |
766 | { | |
767 | 0 | p = " "; |
768 | } | |
769 | } | |
770 | else | |
771 | { | |
772 | 0 | if ((fmt == 'o') && alternate && (r.length() > 0) |
773 | && (r.charAt(0) != '0')) | |
774 | { | |
775 | 0 | p = "0"; |
776 | } | |
777 | 0 | else if ((fmt == 'x') && alternate) |
778 | { | |
779 | 0 | p = "0x"; |
780 | } | |
781 | 0 | else if ((fmt == 'X') && alternate) |
782 | { | |
783 | 0 | p = "0X"; |
784 | } | |
785 | } | |
786 | ||
787 | 185635 | int w = 0; |
788 | ||
789 | 185633 | if (leading_zeroes) |
790 | { | |
791 | 0 | w = width; |
792 | } | |
793 | 185631 | else if (((fmt == 'd') || (fmt == 'i') || (fmt == 'x') || (fmt == 'X') |
794 | || (fmt == 'o')) && (precision > 0)) | |
795 | { | |
796 | 0 | w = precision; |
797 | } | |
798 | ||
799 | 185630 | return p + repeat('0', w - p.length() - r.length()) + r; |
800 | } | |
801 | ||
802 | /** | |
803 | * DOCUMENT ME! | |
804 | * | |
805 | * @param d | |
806 | * DOCUMENT ME! | |
807 | * | |
808 | * @return DOCUMENT ME! | |
809 | */ | |
810 | 144590 | private String fixed_format(double d) |
811 | { | |
812 | 144593 | boolean removeTrailing = ((fmt == 'G') || (fmt == 'g')) && !alternate; |
813 | ||
814 | // remove trailing zeroes and decimal point | |
815 | 144592 | if (d > 0x7FFFFFFFFFFFFFFFL) |
816 | { | |
817 | 0 | return exp_format(d); |
818 | } | |
819 | ||
820 | 144590 | if (precision == 0) |
821 | { | |
822 | 6 | return (long) (d + 0.5) + (removeTrailing ? "" : "."); |
823 | } | |
824 | ||
825 | 144585 | long whole = (long) d; |
826 | 144584 | double fr = d - whole; // fractional part |
827 | ||
828 | 144584 | if ((fr >= 1) || (fr < 0)) |
829 | { | |
830 | 0 | return exp_format(d); |
831 | } | |
832 | ||
833 | 144585 | double factor = 1; |
834 | 144582 | String leading_zeroes = ""; |
835 | ||
836 | 865263 | for (int i = 1; (i <= precision) |
837 | && (factor <= 0x7FFFFFFFFFFFFFFFL); i++) | |
838 | { | |
839 | 720715 | factor *= 10; |
840 | 720742 | leading_zeroes = leading_zeroes + "0"; |
841 | } | |
842 | ||
843 | 144586 | long l = (long) ((factor * fr) + 0.5); |
844 | ||
845 | 144586 | if (l >= factor) |
846 | { | |
847 | 8 | l = 0; |
848 | 8 | whole++; |
849 | } | |
850 | ||
851 | // CSH 10-25-97 | |
852 | 144586 | String z = leading_zeroes + l; |
853 | 144580 | z = "." + z.substring(z.length() - precision, z.length()); |
854 | ||
855 | 144588 | if (removeTrailing) |
856 | { | |
857 | 0 | int t = z.length() - 1; |
858 | ||
859 | 0 | while ((t >= 0) && (z.charAt(t) == '0')) |
860 | { | |
861 | 0 | t--; |
862 | } | |
863 | ||
864 | 0 | if ((t >= 0) && (z.charAt(t) == '.')) |
865 | { | |
866 | 0 | t--; |
867 | } | |
868 | ||
869 | 0 | z = z.substring(0, t + 1); |
870 | } | |
871 | ||
872 | 144587 | return whole + z; |
873 | } | |
874 | ||
875 | /** | |
876 | * DOCUMENT ME! | |
877 | * | |
878 | * @param d | |
879 | * DOCUMENT ME! | |
880 | * | |
881 | * @return DOCUMENT ME! | |
882 | */ | |
883 | 3 | private String exp_format(double d) |
884 | { | |
885 | 3 | String f = ""; |
886 | 3 | int e = 0; |
887 | 3 | double dd = d; |
888 | ||
889 | 3 | if (d != 0) |
890 | { | |
891 | 10 | while (dd > 10) |
892 | { | |
893 | 7 | e++; |
894 | 7 | dd = dd / 10; |
895 | } | |
896 | ||
897 | 313 | while (dd < 1) |
898 | { | |
899 | 310 | e--; |
900 | 310 | dd = dd * 10; |
901 | } | |
902 | } | |
903 | ||
904 | 3 | if (((fmt == 'g') || (fmt == 'G')) && (e >= -4) && (e < precision)) |
905 | { | |
906 | 0 | return fixed_format(d); |
907 | } | |
908 | ||
909 | 3 | f = f + fixed_format(dd); |
910 | ||
911 | 3 | if ((fmt == 'e') || (fmt == 'g')) |
912 | { | |
913 | 3 | f = f + "e"; |
914 | } | |
915 | else | |
916 | { | |
917 | 0 | f = f + "E"; |
918 | } | |
919 | ||
920 | 3 | String p = "000"; |
921 | ||
922 | 3 | if (e >= 0) |
923 | { | |
924 | 2 | f = f + "+"; |
925 | 2 | p = p + e; |
926 | } | |
927 | else | |
928 | { | |
929 | 1 | f = f + "-"; |
930 | 1 | p = p + (-e); |
931 | } | |
932 | ||
933 | 3 | return f + p.substring(p.length() - 3, p.length()); |
934 | } | |
935 | ||
936 | 0 | @Override |
937 | public String toString() | |
938 | { | |
939 | 0 | return formatString; |
940 | } | |
941 | ||
942 | /** | |
943 | * Bespoke method to format a percentage (or any other) float value to the | |
944 | * specified number of decimal places. Avoids use of general-purpose format | |
945 | * parsers as a processing hotspot. | |
946 | * | |
947 | * @param sb | |
948 | * @param value | |
949 | * @param dp | |
950 | */ | |
951 | 257957 | public static void appendPercentage(StringBuilder sb, float value, int dp) |
952 | { | |
953 | /* | |
954 | * rounding first | |
955 | */ | |
956 | 257957 | double d = value; |
957 | 257957 | long factor = 1L; |
958 | 257973 | for (int i = 0; i < dp; i++) |
959 | { | |
960 | 16 | factor *= 10; |
961 | } | |
962 | 257957 | d *= factor; |
963 | 257957 | d += 0.5; |
964 | ||
965 | /* | |
966 | * integer part | |
967 | */ | |
968 | 257957 | value = (float) (d / factor); |
969 | 257957 | sb.append((long) value); |
970 | ||
971 | /* | |
972 | * decimal places | |
973 | */ | |
974 | 257957 | if (dp > 0) |
975 | { | |
976 | 10 | sb.append("."); |
977 | 26 | while (dp > 0) |
978 | { | |
979 | 16 | value = value - (int) value; |
980 | 16 | value *= 10; |
981 | 16 | sb.append((int) value); |
982 | 16 | dp--; |
983 | } | |
984 | } | |
985 | } | |
986 | } |