Significant Figures : Rational « Data Type « Java






Significant Figures

 
/*
 * Copyright (C) 2002-2007 Stephen Ostermiller
 * http://ostermiller.org/contact.pl?regarding=Java+Utilities
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * See COPYING.TXT for details.
 */


/**
 * A number with an associated number of significant figures.
 * This class handles parsing numbers, determining the number
 * of significant figures, adjusting the number of significant
 * figures (including scientific rounding), and displaying the number.
 * More information about this class is available from <a target="_top" href=
 * "http://ostermiller.org/utils/SignificantFigures.html">ostermiller.org</a>.
 * <p>
 * When parsing a number to determine the number of significant figures,
 * these rules are used:
 * <ul>
 * <li>Non-zero digits are always significant.</li>
 * <li>All zeros between other significant digits are significant.</li>
 * <li>All zeros left of the decimal point between a significant digit and the decimal point are significant.</li>
 * <li>All trailing zeros to the right of the decimal point are significant.</li>
 * <li>If the number is contains no digits other than zero, every zero is significant.</li>
 * </ul>
 * <p>
 * When rounding a number the following rules are used:
 * <ul>
 * <li>If the greatest insignificant digit is less than five, round down.</li>
 * <li>If the greatest insignificant digit is greater than five, round up.</li>
 * <li>If the greatest insignificant digit is five and followed by some non-zero digit, round up.</li>
 * <li>If the greatest insignificant digit is five and followed only by zeros, and the least significant
 * digit is odd, round up.</li>
 * <li>If the greatest insignificant digit is five and followed only by zeros, and the least significant
 * digit is even, round down.</li>
 * </ul>
 *
 * <p>
 * Example of using this class to multiply numbers and display the result
 * with the proper number of significant figures:<br>
 * <pre> String[] arguments = {"1.0", "2.0", ...}
 * SignificantFigures number;
 * int sigFigs = Integer.MAX_VALUE;
 * double result = 1D;
 * for (int i=0; i&lt;arguments.length; i++){
 * &nbsp;   number = new SignificantFigures(arguments[i]);
 * &nbsp;   sigFigs = Math.min(sigFigs, number.getNumberSignificantFigures());
 * &nbsp;   result *= number.doubleValue();
 * }
 * number = new SignificantFigures(result);
 * number.setNumberSignificantFigures(sigFigs);
 * System.out.println(number);</pre>
 * <p>
 * Example of using this class to add numbers and display the result
 * with the proper number of significant figures:<br>
 * <pre> String[] arguments = {"1.0", "2.0", ...}
 * SignificantFigures number;
 * int leastSD = Integer.MIN_VALUE;
 * int mostSD = Integer.MIN_VALUE;
 * double result = 0D;
 * for (int i=0; i&lt;arguments.length; i++){
 * &nbsp;   number = new SignificantFigures(arguments[i]);
 * &nbsp;   leastSD = Math.max(leastSD, number.getLSD());
 * &nbsp;   mostSD = Math.max(mostSD, number.getMSD());
 * &nbsp;   result += number.doubleValue();
 * }
 * number = new SignificantFigures(result);
 * number.setLMSD(leastSD, mostSD);
 * System.out.println(number);</pre>
 *
 * @author Stephen Ostermiller http://ostermiller.org/contact.pl?regarding=Java+Utilities
 * @since ostermillerutils 1.00.00
 */
public class SignificantFigures extends Number {

  /**
   *
   */
  private static final long serialVersionUID = -1130798283937219608L;
  /**
   * In the case the a number
   * could not be parsed, the original is stored
   * for toString purposes.
   *
   * @since ostermillerutils 1.00.00
   */
  private String original;
  /**
   * Buffer of the significant digits.
   *
   * @since ostermillerutils 1.00.00
   */
  private StringBuffer digits;
  /**
   * The exponent of the digits if a
   * decimal place were inserted after
   * the first digit.
   *
   * @since ostermillerutils 1.00.00
   */
  private int mantissa = -1;
  /**
   * positive if true, negative if false.
   *
   * @since ostermillerutils 1.00.00
   */
  private boolean sign = true;
  /**
   * True if this number has no non-zero digits.
   *
   * @since ostermillerutils 1.00.00
   */
  private boolean isZero = false;

  /**
   * Create a SignificantFigures object from a String representation of a number.
   *
   * @param number String representation of the number.
   * @throws NumberFormatException if the String is not a valid number.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures(String number) throws NumberFormatException {
    original = number;
    parse(original);
  }

  /**
   * Create a SignificantFigures object from a byte.
   *
   * @param number an 8 bit integer.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures(byte number){
    original = Byte.toString(number);
    try {
      parse(original);
    } catch (NumberFormatException nfe){
      digits = null;
    }
  }

  /**
   * Create a SignificantFigures object from a short.
   *
   * @param number a 16 bit integer.
   *
   * @since ostermillerutils 1.00.00
   */
   public SignificantFigures(short number){
    original = Short.toString(number);
    try {
      parse(original);
    } catch (NumberFormatException nfe){
      digits = null;
    }
  }

  /**
   * Create a SignificantFigures object from an integer.
   *
   * @param number a 32 bit integer.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures(int number){
    original = String.valueOf(number);
    try {
      parse(original);
    } catch (NumberFormatException nfe){
      digits = null;
    }
  }

  /**
   * Create a SignificantFigures object from a long.
   *
   * @param number a 64 bit integer.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures(long number){
    original = Long.toString(number);
    try {
      parse(original);
    } catch (NumberFormatException nfe){
      digits = null;
    }
  }

  /**
   * Create a SignificantFigures object from a float.
   *
   * @param number a 32 bit floating point.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures(float number){
    original = Float.toString(number);
    try {
      parse(original);
    } catch (NumberFormatException nfe){
      digits = null;
    }
  }

  /**
   * Create a SignificantFigures object from a double.
   *
   * @param number a 64 bit floating point.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures(double number){
    original = Double.toString(number);
    try {
      parse(original);
    } catch (NumberFormatException nfe){
      digits = null;
    }
  }

  /**
   * Create a SignificantFigures object from a java number such as
   * a BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, or
   * Short.
   *
   * @param number a number.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures(Number number){
    original = number.toString();
    try {
      parse(original);
    } catch (NumberFormatException nfe){
      digits = null;
    }
  }

  /**
   * Get the number of significant digits.
   * <p>
   * If this number is not a number or infinity zero
   * will be returned.
   *
   * @return the number of significant digits in this number.
   *
   * @since ostermillerutils 1.00.00
   */
  public int getNumberSignificantFigures() {
    if (digits == null) return 0;
    return digits.length();
  }

  /**
   * Adjust the number of significant figures such that the least
   * significant digit is at the given place.  This method may add
   * significant zeros to the end of this number, or remove significant
   * digits from this number.
   * <p>
   * It is possible to remove all significant digits from this number which
   * will cause the string representation of this number to become "NaN".  This
   * could become a problem if you are adding numbers and the result is close
   * to zero.  All of the significant digits may get removed, even though the
   * result could be zero with some number of significant digits.  Its is safes
   * to use the setLMSD() method which will make a zero with the appropriate
   * number of significant figures in such instances.
   * <p>
   * This method has no effect if this number is not a number or infinity.
   *
   * @param place the desired place of the least significant digit.
   * @return this number.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures setLSD(int place){
    setLMSD(place, Integer.MIN_VALUE);
    return this;
  }

  /**
   * Adjust the number of significant figures such that the least
   * significant digit is at the given place.  This method may add
   * significant zeros to the end of this number, or remove significant
   * digits from this number.
   * <p>
   * If all significant digits are removed from this number by truncating to
   * the least significant place, a zero will be created with significant figures
   * from the least to most significant places.
   * <p>
   * This method has no effect if this number is not a number or infinity.
   *
   * @param leastPlace the desired place of the least significant digit or Integer.MIN_VALUE to ignore.
   * @param mostPlace the desired place of the most significant digit or Integer.MIN_VALUE to ignore.
   * @return this number
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures setLMSD(int leastPlace, int mostPlace){
    if (digits != null && leastPlace != Integer.MIN_VALUE){
      int significantFigures = digits.length();
      int current = mantissa - significantFigures + 1;
      int newLength = significantFigures - leastPlace + current;
      if (newLength <= 0){
        if (mostPlace == Integer.MIN_VALUE){
          original = "NaN";
          digits = null;
        } else {
          newLength = mostPlace - leastPlace + 1;
          digits.setLength(newLength);
          mantissa = leastPlace;
          for (int i=0; i<newLength; i++){
            digits.setCharAt(i, '0');
          }
          isZero = true;
          sign = true;
        }
      } else {
        digits.setLength(newLength);
        for (int i=significantFigures; i<newLength; i++){
          digits.setCharAt(i, '0');
        }
      }
    }
    return this;
  }

  /**
   * Get the decimal place of the least significant digit.
   * <p>
   * If this number is not a number or infinity Integer.MIN_VALUE
   * will be returned.
   *
   * @return the decimal place of the least significant digit.
   *
   * @since ostermillerutils 1.00.00
   */
  public int getLSD(){
    if (digits == null) return Integer.MIN_VALUE;
    return mantissa - digits.length() + 1;
  }

  /**
   * Get the decimal place of the most significant digit.
   * <p>
   * If this number is not a number or infinity Integer.MIN_VALUE
   * will be returned.
   *
   * @return the decimal place of the least significant digit.
   *
   * @since ostermillerutils 1.00.00
   */
  public int getMSD(){
    if (digits == null) return Integer.MIN_VALUE;
    return mantissa + 1;
  }

  /**
   * Formats this number.
   * If the number is less than 10^-3 or greater than or equal to 10^7,
   * or the number might have an ambiguous number of significant figures,
   * scientific notation will be used.
   * <p>
   * A string such as "NaN" or "Infinity" may be returned by this method.
   *
   * @return representation of this number.
   *
   * @since ostermillerutils 1.00.00
   */
  @Override public String toString() {
    if (digits == null) return original;
    StringBuffer digits = new StringBuffer(this.digits.toString());
    int length = digits.length();
    if (mantissa <= -4 || mantissa >= 7 ||
        (mantissa >= length &&
        digits.charAt(digits.length()-1) == '0') ||
        (isZero && mantissa != 0)) {
      // use scientific notation.
      if (length > 1){
        digits.insert(1, '.');
      }
      if (mantissa != 0){
        digits.append("E" + mantissa);
      }
    } else if (mantissa <= -1){
      digits.insert(0, "0.");
      for (int i=mantissa; i<-1; i++){
        digits.insert(2, '0');
      }
    } else if (mantissa+1 == length){
      if (length > 1 && digits.charAt(digits.length()-1) == '0'){
        digits.append('.');
      }
    } else if (mantissa < length){
      digits.insert(mantissa+1, '.');
    } else {
      for (int i=length; i<=mantissa; i++){
        digits.append('0');
      }
    }
    if (!sign) {
      digits.insert(0, '-');
    }
    return digits.toString();
  }

  /**
   * Formats this number in scientific notation.
   * <p>
   * A string such as "NaN" or "Infinity" may be returned by this method.
   *
   * @return representation of this number in scientific notation.
   *
   * @since ostermillerutils 1.00.00
   */
  public String toScientificNotation() {
    if (digits == null) return original;
    StringBuffer digits = new StringBuffer(this.digits.toString());
    int length = digits.length();
    if (length > 1){
      digits.insert(1, '.');
    }
    if (mantissa != 0){
      digits.append("E" + mantissa);
    }
    if (!sign) {
      digits.insert(0, '-');
    }
    return digits.toString();
  }

  /**
   * Parsing state:
   * Initial state before anything read.
   *
   * @since ostermillerutils 1.00.00
   */
  private final static int INITIAL = 0;
  /**
   * Parsing state:
   * State in which a possible sign and
   * possible leading zeros have been read.
   *
   * @since ostermillerutils 1.00.00
   */
  private final static int LEADZEROS = 1;
  /**
   * Parsing state:
   * State in which a possible sign and
   * at least one non-zero digit
   * has been read followed by some number of
   * zeros.  The decimal place has no
   * been encountered yet.
   *
   * @since ostermillerutils 1.00.00
   */
  private final static int MIDZEROS = 2;
  /**
   * Parsing state:
   * State in which a possible sign and
   * at least one non-zero digit
   * has been read.  The decimal place has no
   * been encountered yet.
   *
   * @since ostermillerutils 1.00.00
   */
  private final static int DIGITS = 3;
  /**
   * Parsing state:
   * State in which only a possible sign,
   * leading zeros, and a decimal point
   * have been encountered.
   *
   * @since ostermillerutils 1.00.00
   */
  private final static int LEADZEROSDOT = 4;
  /**
   * Parsing state:
   * State in which a possible sign,
   * at least one nonzero digit and a
   * decimal point have been encountered.
   *
   * @since ostermillerutils 1.00.00
   */
  private final static int DIGITSDOT = 5;
  /**
   * Parsing state:
   * State in which the exponent symbol
   * 'E' has been encountered.
   *
   * @since ostermillerutils 1.00.00
   */
  private final static int MANTISSA = 6;
  /**
   * Parsing state:
   * State in which the exponent symbol
   * 'E' has been encountered followed
   * by a possible sign or some number
   * of digits.
   *
   * @since ostermillerutils 1.00.00
   */
  private final static int MANTISSADIGIT = 7;

  /**
   * Parse a number from the given string.
   * A valid number has an optional sign, some digits
   * with an optional decimal point, and an optional
   * scientific notation part consisting of an 'E' followed
   * by an optional sign, followed by some digits.
   *
   * @param number String representation of a number.
   * @throws NumberFormatException if the string is not a valid number.
   *
   * @since ostermillerutils 1.00.00
   */
  private void parse(String number) throws NumberFormatException {
    int length = number.length();
    digits = new StringBuffer(length);
    int state = INITIAL;
    int mantissaStart = -1;
    boolean foundMantissaDigit = false;
    // sometimes we don't know if a zero will be
    // significant or not when it is encountered.
    // keep track of the number of them so that
    // the all can be made significant if we find
    // out that they are.
    int zeroCount = 0;
    int leadZeroCount = 0;

    for (int i=0; i<length; i++){
      char c = number.charAt(i);
      switch (c){
        case '.': {
          switch (state){
            case INITIAL:
            case LEADZEROS: {
              state = LEADZEROSDOT;
            } break;
            case MIDZEROS: {
              // we now know that these zeros
              // are more than just trailing place holders.
              for (int j=0; j<zeroCount; j++){
                digits.append('0');
              }
              zeroCount = 0;
              state = DIGITSDOT;
            } break;
            case DIGITS: {
              state = DIGITSDOT;
            } break;
            default: {
              throw new NumberFormatException (
                "Unexpected character '" + c + "' at position " + i
              );
            }
          }
        } break;
        case '+':{
          switch (state){
            case INITIAL: {
              sign = true;
              state = LEADZEROS;
            } break;
            case MANTISSA: {
              state = MANTISSADIGIT;
            } break;
            default: {
              throw new NumberFormatException (
                "Unexpected character '" + c + "' at position " + i
              );
            }
          }
        } break;
        case '-': {
          switch (state){
            case INITIAL: {
              sign = false;
              state = LEADZEROS;
            } break;
            case MANTISSA: {
              state = MANTISSADIGIT;
            } break;
            default: {
              throw new NumberFormatException (
                "Unexpected character '" + c + "' at position " + i
              );
            }
          }
        } break;
        case '0': {
          switch (state){
            case INITIAL:
            case LEADZEROS: {
              // only significant if number
              // is all zeros.
              zeroCount++;
              leadZeroCount++;
              state = LEADZEROS;
            } break;
            case MIDZEROS:
            case DIGITS: {
              // only significant if followed
              // by a decimal point or nonzero digit.
              mantissa++;
              zeroCount++;
              state = MIDZEROS;
            } break;
            case LEADZEROSDOT:{
              // only significant if number
              // is all zeros.
              mantissa--;
              zeroCount++;
              state = LEADZEROSDOT;
            } break;
            case DIGITSDOT: {
              // non-leading zeros after
              // a decimal point are always
              // significant.
              digits.append(c);
            } break;
            case MANTISSA:
            case MANTISSADIGIT: {
              foundMantissaDigit = true;
              state = MANTISSADIGIT;
            } break;
            default: {
              throw new NumberFormatException (
                "Unexpected character '" + c + "' at position " + i
              );
            }
          }
        } break;
        case '1': case '2': case '3':
        case '4': case '5': case '6':
        case '7': case '8': case '9': {
          switch (state){
            case INITIAL:
            case LEADZEROS:
            case DIGITS: {
              zeroCount = 0;
              digits.append(c);
              mantissa++;
              state = DIGITS;
            } break;
            case MIDZEROS: {
              // we now know that these zeros
              // are more than just trailing place holders.
              for (int j=0; j<zeroCount; j++){
                digits.append('0');
              }
              zeroCount = 0;
              digits.append(c);
              mantissa++;
              state = DIGITS;
            } break;
            case LEADZEROSDOT:
            case DIGITSDOT: {
              zeroCount = 0;
              digits.append(c);
              state = DIGITSDOT;
            } break;
            case MANTISSA:
            case MANTISSADIGIT: {
              state = MANTISSADIGIT;
              foundMantissaDigit = true;
            } break;
            default: {
              throw new NumberFormatException (
                "Unexpected character '" + c + "' at position " + i
              );
            }
          }
        } break;
        case 'E': case 'e': {
          switch (state){
            case INITIAL:
            case LEADZEROS:
            case DIGITS:
            case LEADZEROSDOT:
            case DIGITSDOT: {
              // record the starting point of the mantissa
              // so we can do a substring to get it back later
              mantissaStart = i+1;
              state = MANTISSA;
            } break;
            default: {
              throw new NumberFormatException (
                "Unexpected character '" + c + "' at position " + i
              );
            }
          }
        } break;
        default: {
          throw new NumberFormatException (
            "Unexpected character '" + c + "' at position " + i
          );
        }
      }
    }
    if (mantissaStart != -1){
      // if we had found an 'E'
      if (!foundMantissaDigit){
        // we didn't actually find a mantissa to go with.
        throw new NumberFormatException (
          "No digits in mantissa."
        );
      }
      // parse the mantissa.
      mantissa += Integer.parseInt(number.substring(mantissaStart));
    }
    if (digits.length() == 0){
      if (zeroCount > 0){
        // if nothing but zeros all zeros are significant.
        for (int j=0; j<zeroCount; j++){
          digits.append('0');
        }
        mantissa += leadZeroCount;
        isZero = true;
        sign = true;
      } else {
        // a hack to catch some cases that we could catch
        // by adding a ton of extra states.  Things like:
        // "e2" "+e2" "+." "." "+" etc.
        throw new NumberFormatException (
          "No digits in number."
        );
      }
    }
  }

  /**
   * Adjust the number of digits in the number.
   * Pad the tail with zeros if too short, round the
   * number according to scientific rounding if too long, leave alone
   * if just right.
   * <p>
   * This method has no effect if this number is not a number or infinity.
   *
   * @param significantFigures desired number of significant figures.
   * @return This number.
   *
   * @since ostermillerutils 1.00.00
   */
  public SignificantFigures setNumberSignificantFigures(int significantFigures){
    if (significantFigures <= 0) throw new IllegalArgumentException("Desired number of significant figures must be positive.");
    if (digits != null) {
      int length =  digits.length();
      if (length < significantFigures){
        // number is not long enough, pad it with zeros.
        for (int i=length; i<significantFigures; i++){
          digits.append('0');
        }
      } else if (length > significantFigures){
        // number is too long chop some of it off with rounding.
        boolean addOne; // we need to round up if true.
        char firstInSig = digits.charAt(significantFigures);
        if (firstInSig < '5'){
          // first non-significant digit less than five, round down.
          addOne = false;
        } else if (firstInSig == '5'){
          // first non-significant digit equal to five
          addOne = false;
          for (int i=significantFigures+1; !addOne && i<length; i++){
            // if its followed by any non-zero digits, round up.
            if (digits.charAt(i) != '0'){
              addOne = true;
            }
          }
          if (!addOne){
            // if it was not followed by non-zero digits
            // if the last significant digit is odd round up
            // if the last significant digit is even round down
            addOne = (digits.charAt(significantFigures-1) & 1) == 1;
          }
        } else {
          // first non-significant digit greater than five, round up.
          addOne = true;
        }
        // loop to add one (and carry a one if added to a nine)
        // to the last significant digit
        for (int i=significantFigures-1; addOne && i>=0; i--){
          char digit = digits.charAt(i);
          if (digit < '9'){
            digits.setCharAt(i, (char)(digit+1));
            addOne = false;
          } else {
            digits.setCharAt(i, '0');
          }
        }
        if (addOne){
          // if the number was all nines
          digits.insert(0, '1');
          mantissa++;
        }
        // chop it to the correct number of figures.
        digits.setLength(significantFigures);
      }
    }
    return this;
  }

  /**
   * Returns the value of this number as a byte.
   *
   * @return the numeric value represented by this object after conversion to type byte.
   * @throws NumberFormatException if this number cannot be converted to a byte.
   *
   * @since ostermillerutils 1.00.00
   */
  @Override public byte byteValue() throws NumberFormatException {
    return Byte.parseByte(original);
  }

  /**
   * Returns the value of this number as a double.
   *
   * @return the numeric value represented by this object after conversion to type double.
   * @throws NumberFormatException if this number cannot be converted to a double.
   *
   * @since ostermillerutils 1.00.00
   */
  @Override public double doubleValue() throws NumberFormatException {
    return Double.parseDouble(original);
  }

  /**
   * Returns the value of this number as a float.
   *
   * @return the numeric value represented by this object after conversion to type float.
   * @throws NumberFormatException if this number cannot be converted to a float.
   *
   * @since ostermillerutils 1.00.00
   */
  @Override public float floatValue() throws NumberFormatException {
    return Float.parseFloat(original);
  }

  /**
   * Returns the value of this number as a int.
   *
   * @return the numeric value represented by this object after conversion to type int.
   * @throws NumberFormatException if this number cannot be converted to a int.
   *
   * @since ostermillerutils 1.00.00
   */
  @Override public int intValue() throws NumberFormatException {
    return Integer.parseInt(original);
  }

  /**
   * Returns the value of this number as a long.
   *
   * @return the numeric value represented by this object after conversion to type long.
   * @throws NumberFormatException if this number cannot be converted to a long.
   *
   * @since ostermillerutils 1.00.00
   */
  @Override public long longValue() throws NumberFormatException {
    return Long.parseLong(original);
  }

  /**
   * Returns the value of this number as a short.
   *
   * @return the numeric value represented by this object after conversion to type short.
   * @throws NumberFormatException if this number cannot be converted to a short.
   *
   * @since ostermillerutils 1.00.00
   */
  @Override public short shortValue() throws NumberFormatException {
    return Short.parseShort(original);
  }

  /**
   * Convenience method to display a number with the correct
   * significant digits.
   *
   * @param number the number to display
   * @param significantFigures the number of significant figures to display.
   * @return the number formatted with the correct significant figures
   *
   * @since ostermillerutils 1.02.07
   */
  public static String format(byte number, int significantFigures){
    SignificantFigures sf = new SignificantFigures(number);
    sf.setNumberSignificantFigures(significantFigures);
    return sf.toString();
  }

  /**
   * Convenience method to display a number with the correct
   * significant digits.
   *
   * @param number the number to display
   * @param significantFigures the number of significant figures to display.
   * @return the number formatted with the correct significant figures
   *
   * @since ostermillerutils 1.02.07
   */
  public static String format(double number, int significantFigures){
    SignificantFigures sf = new SignificantFigures(number);
    sf.setNumberSignificantFigures(significantFigures);
    return sf.toString();
  }

  /**
   * Convenience method to display a number with the correct
   * significant digits.
   *
   * @param number the number to display
   * @param significantFigures the number of significant figures to display.
   * @return the number formatted with the correct significant figures
   *
   * @since ostermillerutils 1.02.07
   */
  public static String format(float number, int significantFigures){
    SignificantFigures sf = new SignificantFigures(number);
    sf.setNumberSignificantFigures(significantFigures);
    return sf.toString();
  }

  /**
   * Convenience method to display a number with the correct
   * significant digits.
   *
   * @param number the number to display
   * @param significantFigures the number of significant figures to display.
   * @return the number formatted with the correct significant figures
   *
   * @since ostermillerutils 1.02.07
   */
  public static String format(int number, int significantFigures){
    SignificantFigures sf = new SignificantFigures(number);
    sf.setNumberSignificantFigures(significantFigures);
    return sf.toString();
  }

  /**
   * Convenience method to display a number with the correct
   * significant digits.
   *
   * @param number the number to display
   * @param significantFigures the number of significant figures to display.
   * @return the number formatted with the correct significant figures
   *
   * @since ostermillerutils 1.02.07
   */
  public static String format(long number, int significantFigures){
    SignificantFigures sf = new SignificantFigures(number);
    sf.setNumberSignificantFigures(significantFigures);
    return sf.toString();
  }

  /**
   * Convenience method to display a number with the correct
   * significant digits.
   *
   * @param number the number to display
   * @param significantFigures the number of significant figures to display.
   * @return the number formatted with the correct significant figures
   *
   * @since ostermillerutils 1.02.07
   */
  public static String format(Number number, int significantFigures){
    SignificantFigures sf = new SignificantFigures(number);
    sf.setNumberSignificantFigures(significantFigures);
    return sf.toString();
  }

  /**
   * Convenience method to display a number with the correct
   * significant digits.
   *
   * @param number the number to display
   * @param significantFigures the number of significant figures to display.
   * @return the number formatted with the correct significant figures
   *
   * @since ostermillerutils 1.02.07
   */
  public static String format(short number, int significantFigures){
    SignificantFigures sf = new SignificantFigures(number);
    sf.setNumberSignificantFigures(significantFigures);
    return sf.toString();
  }

  /**
   * Convenience method to display a number with the correct
   * significant digits.
   *
   * @param number the number to display
   * @param significantFigures the number of significant figures to display.
   * @return the number formatted with the correct significant figures
   * @throws NumberFormatException if the String is not a valid number.
   *
   * @since ostermillerutils 1.02.07
   */
  public static String format(String number, int significantFigures) throws NumberFormatException {
    SignificantFigures sf = new SignificantFigures(number);
    sf.setNumberSignificantFigures(significantFigures);
    return sf.toString();
  }
}

   
  








Related examples in the same category

1.Immutable class for holding a rational number without loss of precision