KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > Ostermiller > util > SignificantFigures


1 /*
2  * Routines for working with numbers in scientific notation.
3  * Copyright (C) 2002 Stephen Ostermiller
4  * http://ostermiller.org/contact.pl?regarding=Java+Utilities
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * See COPYING.TXT for details.
17  */

18
19 package com.Ostermiller.util;
20
21 /**
22  * A number with an associated number of significant figures.
23  * This class handles parsing numbers, determining the number
24  * of significant figures, adjusting the number of significant
25  * figures (including scientific rounding), and displaying the number.
26  * More information about this class is available from <a target="_top" HREF=
27  * "http://ostermiller.org/utils/SignificantFigures.html">ostermiller.org</a>.
28  * <p>
29  * When parsing a number to determine the number of significant figures,
30  * these rules are used:
31  * <ul>
32  * <li>Non-zero digits are always significant.</li>
33  * <li>All zeros between other significant digits are significant.</li>
34  * <li>All zeros left of the decimal point between a significant digit and the decimal point are significant.</li>
35  * <li>All trailing zeros to the right of the decimal point are significant.</li>
36  * <li>If the number is contains no digits other than zero, every zero is significant.</li>
37  * </ul>
38  * <p>
39  * When rounding a number the following rules are used:
40  * <ul>
41  * <li>If the greatest insignificant digit is less than five, round down.</li>
42  * <li>If the greatest insignificant digit is greater than five, round up.</li>
43  * <li>If the greatest insignificant digit is five and followed by some non-zero digit, round up.</li>
44  * <li>If the greatest insignificant digit is five and followed only by zeros, and the least significant
45  * digit is odd, round up.</li>
46  * <li>If the greatest insignificant digit is five and followed only by zeros, and the least significant
47  * digit is even, round down.</li>
48  * </ul>
49  *
50  * <p>
51  * Example of using this class to multiply numbers and display the result
52  * with the proper number of significant figures:<br>
53  * <pre> String[] args = {"1.0", "2.0", ...}
54  * SignificantFigures number;
55  * int sigs = Integer.MAX_VALUE;
56  * double result = 1D;
57  * for (int i=0; i&lt;args.length; i++){
58  * &nbsp; number = new SignificantFigures(args[i]);
59  * &nbsp; sigs = Math.min(sigs, number.getNumberSignificantFigures());
60  * &nbsp; result *= number.doubleValue();
61  * }
62  * number = new SignificantFigures(result);
63  * number.setNumberSignificantFigures(sigs);
64  * System.out.println(number);</pre>
65  * <p>
66  * Example of using this class to add numbers and display the result
67  * with the proper number of significant figures:<br>
68  * <pre> String[] args = {"1.0", "2.0", ...}
69  * SignificantFigures number;
70  * int lsd = Integer.MIN_VALUE;
71  * int msd = Integer.MIN_VALUE;
72  * double result = 0D;
73  * for (int i=0; i&lt;args.length; i++){
74  * &nbsp; number = new SignificantFigures(args[i]);
75  * &nbsp; lsd = Math.max(lsd, number.getLSD());
76  * &nbsp; msd = Math.max(msd, number.getMSD());
77  * &nbsp; result += number.doubleValue();
78  * }
79  * number = new SignificantFigures(result);
80  * number.setLMSD(lsd, msd);
81  * System.out.println(number);</pre>
82  *
83  * @author Stephen Ostermiller http://ostermiller.org/contact.pl?regarding=Java+Utilities
84  * @since ostermillerutils 1.00.00
85  */

86 public class SignificantFigures extends Number JavaDoc {
87
88     /**
89      * In the case the a number
90      * could not be parsed, the original is stored
91      * for toString purposes.
92      *
93      * @since ostermillerutils 1.00.00
94      */

95     private String JavaDoc original;
96     /**
97      * Buffer of the significant digits.
98      *
99      * @since ostermillerutils 1.00.00
100      */

101     private StringBuffer JavaDoc digits;
102     /**
103      * The exponent of the digits if a
104      * decimal place were inserted after
105      * the first digit.
106      *
107      * @since ostermillerutils 1.00.00
108      */

109     private int mantissa = -1;
110     /**
111      * positive if true, negative if false.
112      *
113      * @since ostermillerutils 1.00.00
114      */

115     private boolean sign = true;
116     /**
117      * True if this number has no non-zero digits.
118      *
119      * @since ostermillerutils 1.00.00
120      */

121     private boolean isZero = false;
122
123     /**
124      * Create a SignificantFigures object from a String representation of a number.
125      *
126      * @param number String representation of the number.
127      * @throws NumberFormatException if the String is not a valid number.
128      *
129      * @since ostermillerutils 1.00.00
130      */

131     public SignificantFigures(String JavaDoc number) throws NumberFormatException JavaDoc {
132         original = number;
133         parse(original);
134     }
135
136     /**
137      * Create a SignificantFigures object from a byte.
138      *
139      * @param number an 8 bit integer.
140      *
141      * @since ostermillerutils 1.00.00
142      */

143     public SignificantFigures(byte number){
144         original = Byte.toString(number);
145         try {
146             parse(original);
147         } catch (NumberFormatException JavaDoc nfe){
148             digits = null;
149         }
150     }
151
152     /**
153      * Create a SignificantFigures object from a short.
154      *
155      * @param number a 16 bit integer.
156      *
157      * @since ostermillerutils 1.00.00
158      */

159      public SignificantFigures(short number){
160         original = Short.toString(number);
161         try {
162             parse(original);
163         } catch (NumberFormatException JavaDoc nfe){
164             digits = null;
165         }
166     }
167
168     /**
169      * Create a SignificantFigures object from an integer.
170      *
171      * @param number a 32 bit integer.
172      *
173      * @since ostermillerutils 1.00.00
174      */

175     public SignificantFigures(int number){
176         original = String.valueOf(number);
177         try {
178             parse(original);
179         } catch (NumberFormatException JavaDoc nfe){
180             digits = null;
181         }
182     }
183
184     /**
185      * Create a SignificantFigures object from a long.
186      *
187      * @param number a 64 bit integer.
188      *
189      * @since ostermillerutils 1.00.00
190      */

191     public SignificantFigures(long number){
192         original = Long.toString(number);
193         try {
194             parse(original);
195         } catch (NumberFormatException JavaDoc nfe){
196             digits = null;
197         }
198     }
199
200     /**
201      * Create a SignificantFigures object from a float.
202      *
203      * @param number a 32 bit floating point.
204      *
205      * @since ostermillerutils 1.00.00
206      */

207     public SignificantFigures(float number){
208         original = Float.toString(number);
209         try {
210             parse(original);
211         } catch (NumberFormatException JavaDoc nfe){
212             digits = null;
213         }
214     }
215
216     /**
217      * Create a SignificantFigures object from a double.
218      *
219      * @param number a 64 bit floating point.
220      *
221      * @since ostermillerutils 1.00.00
222      */

223     public SignificantFigures(double number){
224         original = Double.toString(number);
225         try {
226             parse(original);
227         } catch (NumberFormatException JavaDoc nfe){
228             digits = null;
229         }
230     }
231
232     /**
233      * Create a SignificantFigures object from a java number such as
234      * a BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, or
235      * Short.
236      *
237      * @param number a number.
238      *
239      * @since ostermillerutils 1.00.00
240      */

241     public SignificantFigures(Number JavaDoc number){
242         original = number.toString();
243         try {
244             parse(original);
245         } catch (NumberFormatException JavaDoc nfe){
246             digits = null;
247         }
248     }
249
250     /*public static void main(String[] args){
251         int significantFigures = 0;
252         int lsd = Integer.MIN_VALUE;
253         int msd = Integer.MAX_VALUE;
254         for (int i=0; i<args.length; i++){
255             if (args[i].equals("--sigfigs")){
256                 i++;
257                 significantFigures = Integer.parseInt(args[i]);
258             } else if (args[i].equals("--lsd")){
259                 i++;
260                 lsd = Integer.parseInt(args[i]);
261             } else if (args[i].equals("--msd")){
262                 i++;
263                 msd = Integer.parseInt(args[i]);
264             } else {
265                 SignificantFigures sf = new SignificantFigures(args[i]);
266                 System.out.print(args[i] + " ");
267                 System.out.print(sf.getNumberSignificantFigures() + " ");
268                 System.out.print(sf.getLSD() + " ");
269                 if (significantFigures>0) sf.setNumberSignificantFigures(significantFigures);
270                 sf.setLMSD(lsd, msd);
271                 System.out.print(sf.toString() + " ");
272                 System.out.println(sf.toScientificNotation());
273             }
274         }
275     }*/

276
277     /**
278      * Get the number of significant digits.
279      * <p>
280      * If this number is not a number or infinity zero
281      * will be returned.
282      *
283      * @return the number of significant digits in this number.
284      *
285      * @since ostermillerutils 1.00.00
286      */

287     public int getNumberSignificantFigures() {
288         if (digits == null) return 0;
289         return digits.length();
290     }
291
292     /**
293      * Adjust the number of significant figures such that the least
294      * significant digit is at the given place. This method may add
295      * significant zeros to the end of this number, or remove significant
296      * digits from this number.
297      * <p>
298      * It is possible to remove all significant digits from this number which
299      * will cause the string representation of this number to become "NaN". This
300      * could become a problem if you are adding numbers and the result is close
301      * to zero. All of the significant digits may get removed, even though the
302      * result could be zero with some number of significant digits. Its is safes
303      * to use the setLMSD() method which will make a zero with the appropriate
304      * number of significant figures in such instances.
305      * <p>
306      * This method has no effect if this number is not a number or infinity.
307      *
308      * @param place the desired place of the least significant digit.
309      * @return this number.
310      *
311      * @since ostermillerutils 1.00.00
312      */

313     public SignificantFigures setLSD(int place){
314         setLMSD(place, Integer.MIN_VALUE);
315         return this;
316     }
317
318     /**
319      * Adjust the number of significant figures such that the leas
320      * significant digit is at the given place. This method may add
321      * significant zeros to the end of this number, or remove significant
322      * digits from this number.
323      * <p>
324      * If all significant digits are removed from this number by truncating to
325      * the least significant place, a zero will be created with significant figures
326      * from the least to most significant places.
327      * <p>
328      * This method has no effect if this number is not a number or infinity.
329      *
330      * @param leastPlace the desired place of the least significant digit or Integer.MIN_VALUE to ignore.
331      * @param mostPlace the desired place of the most significant digit or Integer.MIN_VALUE to ignore.
332      * @return this number
333      *
334      * @since ostermillerutils 1.00.00
335      */

336     public SignificantFigures setLMSD(int leastPlace, int mostPlace){
337         if (digits != null && leastPlace != Integer.MIN_VALUE){
338             int significantFigures = digits.length();
339             int current = mantissa - significantFigures + 1;
340             int newLength = significantFigures - leastPlace + current;
341             if (newLength <= 0){
342                 if (mostPlace == Integer.MIN_VALUE){
343                     original = "NaN";
344                     digits = null;
345                 } else {
346                     newLength = mostPlace - leastPlace + 1;
347                     digits.setLength(newLength);
348                     mantissa = leastPlace;
349                     for (int i=0; i<newLength; i++){
350                         digits.setCharAt(i, '0');
351                     }
352                     isZero = true;
353                     sign = true;
354                 }
355             } else {
356                 digits.setLength(newLength);
357                 for (int i=significantFigures; i<newLength; i++){
358                     digits.setCharAt(i, '0');
359                 }
360             }
361         }
362         return this;
363     }
364
365     /**
366      * Get the decimal place of the least significant digit.
367      * <p>
368      * If this number is not a number or infinity Integer.MIN_VALUE
369      * will be returned.
370      *
371      * @return the decimal place of the least significant digit.
372      *
373      * @since ostermillerutils 1.00.00
374      */

375     public int getLSD(){
376         if (digits == null) return Integer.MIN_VALUE;
377         return mantissa - digits.length() + 1;
378     }
379
380     /**
381      * Get the decimal place of the most significant digit.
382      * <p>
383      * If this number is not a number or infinity Integer.MIN_VALUE
384      * will be returned.
385      *
386      * @return the decimal place of the least significant digit.
387      *
388      * @since ostermillerutils 1.00.00
389      */

390     public int getMSD(){
391         if (digits == null) return Integer.MIN_VALUE;
392         return mantissa + 1;
393     }
394
395     /**
396      * Formats this number.
397      * If the number is less than 10^-3 or greater than or equal to 10^7,
398      * or the number might have an ambiguous number of significant figures,
399      * scientific notation will be used.
400      * <p>
401      * A string such as "NaN" or "Infinity" may be returned by this method.
402      *
403      * @return representation of this number.
404      *
405      * @since ostermillerutils 1.00.00
406      */

407     public String JavaDoc toString() {
408         if (digits == null) return original;
409         StringBuffer JavaDoc digits = new StringBuffer JavaDoc(this.digits.toString());
410         int length = digits.length();
411         if (mantissa <= -4 || mantissa >= 7 ||
412                 (mantissa >= length &&
413                 digits.charAt(digits.length()-1) == '0') ||
414                 (isZero && mantissa != 0)) {
415             // use scientific notation.
416
if (length > 1){
417                 digits.insert(1, '.');
418             }
419             if (mantissa != 0){
420                 digits.append("E" + mantissa);
421             }
422         } else if (mantissa <= -1){
423             digits.insert(0, "0.");
424             for (int i=mantissa; i<-1; i++){
425                 digits.insert(2, '0');
426             }
427         } else if (mantissa+1 == length){
428             if (length > 1 && digits.charAt(digits.length()-1) == '0'){
429                 digits.append('.');
430             }
431         } else if (mantissa < length){
432             digits.insert(mantissa+1, '.');
433         } else {
434             for (int i=length; i<=mantissa; i++){
435                 digits.append('0');
436             }
437         }
438         if (!sign) {
439             digits.insert(0, '-');
440         }
441         return digits.toString();
442     }
443
444     /**
445      * Formats this number in scientific notation.
446      * <p>
447      * A string such as "NaN" or "Infinity" may be returned by this method.
448      *
449      * @return representation of this number in scientific notation.
450      *
451      * @since ostermillerutils 1.00.00
452      */

453     public String JavaDoc toScientificNotation() {
454         if (digits == null) return original;
455         StringBuffer JavaDoc digits = new StringBuffer JavaDoc(this.digits.toString());
456         int length = digits.length();
457         if (length > 1){
458             digits.insert(1, '.');
459         }
460         if (mantissa != 0){
461             digits.append("E" + mantissa);
462         }
463         if (!sign) {
464             digits.insert(0, '-');
465         }
466         return digits.toString();
467     }
468
469     /**
470      * Parsing state:
471      * Initial state before anything read.
472      *
473      * @since ostermillerutils 1.00.00
474      */

475     private final static int INITIAL = 0;
476     /**
477      * Parsing state:
478      * State in which a possible sign and
479      * possible leading zeros have been read.
480      *
481      * @since ostermillerutils 1.00.00
482      */

483     private final static int LEADZEROS = 1;
484     /**
485      * Parsing state:
486      * State in which a possible sign and
487      * at least one non-zero digit
488      * has been read followed by some number of
489      * zeros. The decimal place has no
490      * been encountered yet.
491      *
492      * @since ostermillerutils 1.00.00
493      */

494     private final static int MIDZEROS = 2;
495     /**
496      * Parsing state:
497      * State in which a possible sign and
498      * at least one non-zero digit
499      * has been read. The decimal place has no
500      * been encountered yet.
501      *
502      * @since ostermillerutils 1.00.00
503      */

504     private final static int DIGITS = 3;
505     /**
506      * Parsing state:
507      * State in which only a possible sign,
508      * leading zeros, and a decimal point
509      * have been encountered.
510      *
511      * @since ostermillerutils 1.00.00
512      */

513     private final static int LEADZEROSDOT = 4;
514     /**
515      * Parsing state:
516      * State in which a possible sign,
517      * at least one nonzero digit and a
518      * decimal point have been encountered.
519      *
520      * @since ostermillerutils 1.00.00
521      */

522     private final static int DIGITSDOT = 5;
523     /**
524      * Parsing state:
525      * State in which the exponent symbol
526      * 'E' has been encountered.
527      *
528      * @since ostermillerutils 1.00.00
529      */

530     private final static int MANTISSA = 6;
531     /**
532      * Parsing state:
533      * State in which the exponent symbol
534      * 'E' has been encountered followed
535      * by a possible sign or some number
536      * of digits.
537      *
538      * @since ostermillerutils 1.00.00
539      */

540     private final static int MANTISSADIGIT = 7;
541
542     /**
543      * Parse a number from the given string.
544      * A valid number has an optional sign, some digits
545      * with an optional decimal point, and an optional
546      * scientific notation part consisting of an 'E' followed
547      * by an optional sign, followed by some digits.
548      *
549      * @param number String representation of a number.
550      * @throws NumberFormatException if the string is not a valid number.
551      *
552      * @since ostermillerutils 1.00.00
553      */

554     private void parse(String JavaDoc number) throws NumberFormatException JavaDoc {
555         int length = number.length();
556         digits = new StringBuffer JavaDoc(length);
557         int state = INITIAL;
558         int mantissaStart = -1;
559         boolean foundMantissaDigit = false;
560         // sometimes we don't know if a zero will be
561
// significant or not when it is encountered.
562
// keep track of the number of them so that
563
// the all can be made significant if we find
564
// out that they are.
565
int zeroCount = 0;
566         int leadZeroCount = 0;
567
568         for (int i=0; i<length; i++){
569             char c = number.charAt(i);
570             switch (c){
571                 case '.': {
572                     switch (state){
573                         case INITIAL:
574                         case LEADZEROS: {
575                             state = LEADZEROSDOT;
576                         } break;
577                         case MIDZEROS: {
578                             // we now know that these zeros
579
// are more than just trailing placeholders.
580
for (int j=0; j<zeroCount; j++){
581                                 digits.append('0');
582                             }
583                             zeroCount = 0;
584                             state = DIGITSDOT;
585                         } break;
586                         case DIGITS: {
587                             state = DIGITSDOT;
588                         } break;
589                         default: {
590                             throw new NumberFormatException JavaDoc (
591                                 "Unexpected character '" + c + "' at position " + i
592                             );
593                         }
594                     }
595                 } break;
596                 case '+':{
597                     switch (state){
598                         case INITIAL: {
599                             sign = true;
600                             state = LEADZEROS;
601                         } break;
602                         case MANTISSA: {
603                             state = MANTISSADIGIT;
604                         } break;
605                         default: {
606                             throw new NumberFormatException JavaDoc (
607                                 "Unexpected character '" + c + "' at position " + i
608                             );
609                         }
610                     }
611                 } break;
612                 case '-': {
613                     switch (state){
614                         case INITIAL: {
615                             sign = false;
616                             state = LEADZEROS;
617                         } break;
618                         case MANTISSA: {
619                             state = MANTISSADIGIT;
620                         } break;
621                         default: {
622                             throw new NumberFormatException JavaDoc (
623                                 "Unexpected character '" + c + "' at position " + i
624                             );
625                         }
626                     }
627                 } break;
628                 case '0': {
629                     switch (state){
630                         case INITIAL:
631                         case LEADZEROS: {
632                             // only significant if number
633
// is all zeros.
634
zeroCount++;
635                             leadZeroCount++;
636                             state = LEADZEROS;
637                         } break;
638                         case MIDZEROS:
639                         case DIGITS: {
640                             // only significant if followed
641
// by a decimal point or nonzero digit.
642
mantissa++;
643                             zeroCount++;
644                             state = MIDZEROS;
645                         } break;
646                         case LEADZEROSDOT:{
647                             // only significant if number
648
// is all zeros.
649
mantissa--;
650                             zeroCount++;
651                             state = LEADZEROSDOT;
652                         } break;
653                         case DIGITSDOT: {
654                             // non-leading zeros after
655
// a decimal point are always
656
// significant.
657
digits.append(c);
658                         } break;
659                         case MANTISSA:
660                         case MANTISSADIGIT: {
661                             foundMantissaDigit = true;
662                             state = MANTISSADIGIT;
663                         } break;
664                         default: {
665                             throw new NumberFormatException JavaDoc (
666                                 "Unexpected character '" + c + "' at position " + i
667                             );
668                         }
669                     }
670                 } break;
671                 case '1': case '2': case '3':
672                 case '4': case '5': case '6':
673                 case '7': case '8': case '9': {
674                     switch (state){
675                         case INITIAL:
676                         case LEADZEROS:
677                         case DIGITS: {
678                             zeroCount = 0;
679                             digits.append(c);
680                             mantissa++;
681                             state = DIGITS;
682                         } break;
683                         case MIDZEROS: {
684                             // we now know that these zeros
685
// are more than just trailing placeholders.
686
for (int j=0; j<zeroCount; j++){
687                                 digits.append('0');
688                             }
689                             zeroCount = 0;
690                             digits.append(c);
691                             mantissa++;
692                             state = DIGITS;
693                         } break;
694                         case LEADZEROSDOT:
695                         case DIGITSDOT: {
696                             zeroCount = 0;
697                             digits.append(c);
698                             state = DIGITSDOT;
699                         } break;
700                         case MANTISSA:
701                         case MANTISSADIGIT: {
702                             state = MANTISSADIGIT;
703                             foundMantissaDigit = true;
704                         } break;
705                         default: {
706                             throw new NumberFormatException JavaDoc (
707                                 "Unexpected character '" + c + "' at position " + i
708                             );
709                         }
710                     }
711                 } break;
712                 case 'E': case 'e': {
713                     switch (state){
714                         case INITIAL:
715                         case LEADZEROS:
716                         case DIGITS:
717                         case LEADZEROSDOT:
718                         case DIGITSDOT: {
719                             // record the starting point of the mantissa
720
// so we can do a substring to get it back later
721
mantissaStart = i+1;
722                             state = MANTISSA;
723                         } break;
724                         default: {
725                             throw new NumberFormatException JavaDoc (
726                                 "Unexpected character '" + c + "' at position " + i
727                             );
728                         }
729                     }
730                 } break;
731                 default: {
732                     throw new NumberFormatException JavaDoc (
733                         "Unexpected character '" + c + "' at position " + i
734                     );
735                 }
736             }
737         }
738         if (mantissaStart != -1){
739             // if we had found an 'E'
740
if (!foundMantissaDigit){
741                 // we didn't actually find a mantissa to go with.
742
throw new NumberFormatException JavaDoc (
743                     "No digits in mantissa."
744                 );
745             }
746             // parse the mantissa.
747
mantissa += Integer.parseInt(number.substring(mantissaStart));
748         }
749         if (digits.length() == 0){
750             if (zeroCount > 0){
751                 // if nothing but zeros all zeros are significant.
752
for (int j=0; j<zeroCount; j++){
753                     digits.append('0');
754                 }
755                 mantissa += leadZeroCount;
756                 isZero = true;
757                 sign = true;
758             } else {
759                 // a hack to catch some cases that we could catch
760
// by adding a ton of extra states. Things like:
761
// "e2" "+e2" "+." "." "+" etc.
762
throw new NumberFormatException JavaDoc (
763                     "No digits in number."
764                 );
765             }
766         }
767     }
768
769     /**
770      * Adjust the number of digits in the number.
771      * Pad the tail with zeros if too short, round the
772      * number according to scientific rounding if too long, leave alone
773      * if just right.
774      * <p>
775      * This method has no effect if this number is not a number or infinity.
776      *
777      * @param significantFigures desired number of significant figures.
778      * @return This number.
779      *
780      * @since ostermillerutils 1.00.00
781      */

782     public SignificantFigures setNumberSignificantFigures(int significantFigures){
783         if (significantFigures <= 0) throw new IllegalArgumentException JavaDoc("Desired number of significant figures must be positive.");
784         if (digits != null) {
785             int length = digits.length();
786             if (length < significantFigures){
787                 // number is not long enough, pad it with zeros.
788
for (int i=length; i<significantFigures; i++){
789                     digits.append('0');
790                 }
791             } else if (length > significantFigures){
792                 // number is too long chop some of it off with rounding.
793
boolean addOne; // we need to round up if true.
794
char firstInSig = digits.charAt(significantFigures);
795                 if (firstInSig < '5'){
796                     // first non-significant digit less than five, round down.
797
addOne = false;
798                 } else if (firstInSig == '5'){
799                     // first non-significant digit equal to five
800
addOne = false;
801                     for (int i=significantFigures+1; !addOne && i<length; i++){
802                         // if its followed by any non-zero digits, round up.
803
if (digits.charAt(i) != '0'){
804                             addOne = true;
805                         }
806                     }
807                     if (!addOne){
808                         // if it was not followed by non-zero digits
809
// if the last significant digit is odd round up
810
// if the last significant digit is even round down
811
addOne = (digits.charAt(significantFigures-1) & 1) == 1;
812                     }
813                 } else {
814                     // first non-significant digit greater than five, round up.
815
addOne = true;
816                 }
817                 // loop to add one (and carry a one if added to a nine)
818
// to the last significant digit
819
for (int i=significantFigures-1; addOne && i>=0; i--){
820                     char digit = digits.charAt(i);
821                     if (digit < '9'){
822                         digits.setCharAt(i, (char)(digit+1));
823                         addOne = false;
824                     } else {
825                         digits.setCharAt(i, '0');
826                     }
827                 }
828                 if (addOne){
829                     // if the number was all nines
830
digits.insert(0, '1');
831                     mantissa++;
832                 }
833                 // chop it to the correct number of figures.
834
digits.setLength(significantFigures);
835             }
836         }
837         return this;
838     }
839
840     /**
841      * Returns the value of this number as a byte.
842      *
843      * @return the numeric value represented by this object after conversion to type byte.
844      * @throws NumberFormatException if this number cannot be converted to a byte.
845      *
846      * @since ostermillerutils 1.00.00
847      */

848     public byte byteValue() throws NumberFormatException JavaDoc {
849         return Byte.parseByte(original);
850     }
851
852     /**
853      * Returns the value of this number as a double.
854      *
855      * @return the numeric value represented by this object after conversion to type double.
856      * @throws NumberFormatException if this number cannot be converted to a double.
857      *
858      * @since ostermillerutils 1.00.00
859      */

860     public double doubleValue() throws NumberFormatException JavaDoc {
861         return Double.parseDouble(original);
862     }
863
864     /**
865      * Returns the value of this number as a float.
866      *
867      * @return the numeric value represented by this object after conversion to type float.
868      * @throws NumberFormatException if this number cannot be converted to a float.
869      *
870      * @since ostermillerutils 1.00.00
871      */

872     public float floatValue() throws NumberFormatException JavaDoc {
873         return Float.parseFloat(original);
874     }
875
876     /**
877      * Returns the value of this number as a int.
878      *
879      * @return the numeric value represented by this object after conversion to type int.
880      * @throws NumberFormatException if this number cannot be converted to a int.
881      *
882      * @since ostermillerutils 1.00.00
883      */

884     public int intValue() throws NumberFormatException JavaDoc {
885         return Integer.parseInt(original);
886     }
887
888     /**
889      * Returns the value of this number as a long.
890      *
891      * @return the numeric value represented by this object after conversion to type long.
892      * @throws NumberFormatException if this number cannot be converted to a long.
893      *
894      * @since ostermillerutils 1.00.00
895      */

896     public long longValue() throws NumberFormatException JavaDoc {
897         return Long.parseLong(original);
898     }
899
900     /**
901      * Returns the value of this number as a short.
902      *
903      * @return the numeric value represented by this object after conversion to type short.
904      * @throws NumberFormatException if this number cannot be converted to a short.
905      *
906      * @since ostermillerutils 1.00.00
907      */

908     public short shortValue() throws NumberFormatException JavaDoc {
909         return Short.parseShort(original);
910     }
911
912     /**
913      * Convenience method to display a number with the correct
914      * significant digits.
915      *
916      * @param number the number to display
917      * @param significantFigures the number of significant figures to display.
918      *
919      * @since ostermillerutils 1.02.07
920      */

921     public static String JavaDoc format(byte number, int significantFigures){
922         SignificantFigures sf = new SignificantFigures(number);
923         sf.setNumberSignificantFigures(significantFigures);
924         return sf.toString();
925     }
926
927     /**
928      * Convenience method to display a number with the correct
929      * significant digits.
930      *
931      * @param number the number to display
932      * @param significantFigures the number of significant figures to display.
933      *
934      * @since ostermillerutils 1.02.07
935      */

936     public static String JavaDoc format(double number, int significantFigures){
937         SignificantFigures sf = new SignificantFigures(number);
938         sf.setNumberSignificantFigures(significantFigures);
939         return sf.toString();
940     }
941
942     /**
943      * Convenience method to display a number with the correct
944      * significant digits.
945      *
946      * @param number the number to display
947      * @param significantFigures the number of significant figures to display.
948      *
949      * @since ostermillerutils 1.02.07
950      */

951     public static String JavaDoc format(float number, int significantFigures){
952         SignificantFigures sf = new SignificantFigures(number);
953         sf.setNumberSignificantFigures(significantFigures);
954         return sf.toString();
955     }
956
957     /**
958      * Convenience method to display a number with the correct
959      * significant digits.
960      *
961      * @param number the number to display
962      * @param significantFigures the number of significant figures to display.
963      *
964      * @since ostermillerutils 1.02.07
965      */

966     public static String JavaDoc format(int number, int significantFigures){
967         SignificantFigures sf = new SignificantFigures(number);
968         sf.setNumberSignificantFigures(significantFigures);
969         return sf.toString();
970     }
971
972     /**
973      * Convenience method to display a number with the correct
974      * significant digits.
975      *
976      * @param number the number to display
977      * @param significantFigures the number of significant figures to display.
978      *
979      * @since ostermillerutils 1.02.07
980      */

981     public static String JavaDoc format(long number, int significantFigures){
982         SignificantFigures sf = new SignificantFigures(number);
983         sf.setNumberSignificantFigures(significantFigures);
984         return sf.toString();
985     }
986
987     /**
988      * Convenience method to display a number with the correct
989      * significant digits.
990      *
991      * @param number the number to display
992      * @param significantFigures the number of significant figures to display.
993      *
994      * @since ostermillerutils 1.02.07
995      */

996     public static String JavaDoc format(Number JavaDoc number, int significantFigures){
997         SignificantFigures sf = new SignificantFigures(number);
998         sf.setNumberSignificantFigures(significantFigures);
999         return sf.toString();
1000    }
1001
1002    /**
1003     * Convenience method to display a number with the correct
1004     * significant digits.
1005     *
1006     * @param number the number to display
1007     * @param significantFigures the number of significant figures to display.
1008     *
1009     * @since ostermillerutils 1.02.07
1010     */

1011    public static String JavaDoc format(short number, int significantFigures){
1012        SignificantFigures sf = new SignificantFigures(number);
1013        sf.setNumberSignificantFigures(significantFigures);
1014        return sf.toString();
1015    }
1016
1017    /**
1018     * Convenience method to display a number with the correct
1019     * significant digits.
1020     *
1021     * @param number the number to display
1022     * @param significantFigures the number of significant figures to display.
1023     * @throws NumberFormatException if the String is not a valid number.
1024     *
1025     * @since ostermillerutils 1.02.07
1026     */

1027    public static String JavaDoc format(String JavaDoc number, int significantFigures) throws NumberFormatException JavaDoc {
1028        SignificantFigures sf = new SignificantFigures(number);
1029        sf.setNumberSignificantFigures(significantFigures);
1030        return sf.toString();
1031    }
1032}
1033
Popular Tags