/*
 * $Id: Format.java,v 1.4 2002/03/04 16:37:57 dwd Exp $
 *
 * Gary Cornell and Cay S. Horstmann, Core Java (Book/CD-ROM)
 * Published By SunSoft Press/Prentice-Hall
 * Copyright (C) 1996 Sun Microsystems Inc.
 * All Rights Reserved. ISBN 0-13-596891-7
 *
 * Permission to use, copy, modify, and distribute this 
 * software and its documentation for NON-COMMERCIAL purposes
 * and without fee is hereby granted provided that this 
 * copyright notice appears in all copies. 
 * 
 * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR 
 * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER 
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS
 * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED 
 * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING 
 * THIS SOFTWARE OR ITS DERIVATIVES.
 */

package  sgtplot;
import  java.io.*;
import java.lang.Math;


/**
 * A class for formatting numbers that follows printf conventions.
 * Also implements C-like atoi and atof functions
 *
 * @version 1.01 15 Feb 1996 
 * @since 1.0
 * @author Cay Horstmann
 */
public class Format {
  private int width;
  private int precision;
  private String pre;
  private String post;
  private boolean leading_zeroes;
  private boolean show_plus;
  private boolean alternate;
  private boolean show_space;
  private boolean left_align;
  private char fmt;
  private static long parseLong(String s,int base) {
    int i = 0;  int sign = 1;
    long r = 0;
      
    while (i < s.length() && Character.isWhitespace(s.charAt(i))) i++;
    if (i < s.length() && s.charAt(i) == '-') { sign = -1; i++; }
    else if (i < s.length() && s.charAt(i) == '+') { i++; }
    while (i < s.length())
      {  char ch = s.charAt(i);
      if ('0' <= ch && ch < '0' + base)
	r = r * base + ch - '0';
      else if ('A' <= ch && ch < 'A' + base - 10)
	r = r * base + ch - 'A' + 10 ;
      else if ('a' <= ch && ch < 'a' + base - 10)
	r = r * base + ch - 'a' + 10 ;
      else 
	return r * sign;
      i++;
      }
    return r * sign;
  }
  /**
   * a test stub for the format class
   */
   /*public static void main(String[] a)
       {  double x = 1.23456789012;
       double xx= 1.0000006;
       double y = 123;
       double z = 1.2345e30;
       double w = 1.02;
       double u = 1.234e-5;
       int d = 0xCAFE;
       Format.print(System.out, "xx = |%.6f|\n", xx);
       Format.print(System.out, "x = |%f|\n", x);
       Format.print(System.out, "u = |%20f|\n", u);
       Format.print(System.out, "x = |% .5f|\n", x);
       Format.print(System.out, "w = |%20.5f|\n", w);
       Format.print(System.out, "x = |%020.5f|\n", x);
       Format.print(System.out, "x = |%+20.5f|\n", x);
       Format.print(System.out, "x = |%+020.5f|\n", x);
       Format.print(System.out, "x = |% 020.5f|\n", x);
       Format.print(System.out, "y = |%#+20.5f|\n", y);
       Format.print(System.out, "y = |%-+20.5f|\n", y);
       Format.print(System.out, "z = |%20.5f|\n", z);
      
       Format.print(System.out, "x = |%e|\n", x);
       Format.print(System.out, "u = |%20e|\n", u);
       Format.print(System.out, "x = |% .5e|\n", x);
       Format.print(System.out, "w = |%20.5e|\n", w);
       Format.print(System.out, "x = |%020.5e|\n", x);
       Format.print(System.out, "x = |%+20.5e|\n", x);
       Format.print(System.out, "x = |%+020.5e|\n", x);
       Format.print(System.out, "x = |% 020.5e|\n", x);
       Format.print(System.out, "y = |%#+20.5e|\n", y);
       Format.print(System.out, "y = |%-+20.5e|\n", y);
      
       Format.print(System.out, "x = |%g|\n", x);
       Format.print(System.out, "z = |%g|\n", z);
       Format.print(System.out, "w = |%g|\n", w);
       Format.print(System.out, "u = |%g|\n", u);
       Format.print(System.out, "y = |%.2g|\n", y);
       Format.print(System.out, "y = |%#.2g|\n", y);
 
       Format.print(System.out, "d = |%d|\n", d);
       Format.print(System.out, "d = |%20d|\n", d);            
       Format.print(System.out, "d = |%020d|\n", d);    
       Format.print(System.out, "d = |%+20d|\n", d);
       Format.print(System.out, "d = |% 020d|\n", d);
       Format.print(System.out, "d = |%-20d|\n", d);
       Format.print(System.out, "d = |%20.8d|\n", d);
       Format.print(System.out, "d = |%x|\n", d);            
       Format.print(System.out, "d = |%20X|\n", d);    
       Format.print(System.out, "d = |%#20x|\n", d);
       Format.print(System.out, "d = |%020X|\n", d);
       Format.print(System.out, "d = |%20.8x|\n", d);
       Format.print(System.out, "d = |%o|\n", d);            
       Format.print(System.out, "d = |%020o|\n", d);    
       Format.print(System.out, "d = |%#20o|\n", d);
       Format.print(System.out, "d = |%#020o|\n", d);
       Format.print(System.out, "d = |%20.12o|\n", d);
      
       Format.print(System.out, "s = |%-20s|\n", "Hello");      
       Format.print(System.out, "s = |%-20c|\n", '!');      
       }*/
     
  private static String repeat(char c,int n) {
    if (n <= 0) return "";  StringBuffer s = new StringBuffer(n);
    for (int i = 0; i < n; i++) s.append(c);
    return s.toString();
  }
  private static String convert(long x,int n,int m,String d) {
    if (x == 0) return "0";  String r = "";
    while (x != 0)
      {  r = d.charAt((int)(x & m)) + r;
      x = x >>> n;
      }
    return r;
  }
  private String pad(String r) {
    String p = repeat(' ', width - r.length());  if (left_align) return pre + r + p + post;
    else return pre + p + r + post;
  }
  private String sign(int s,String r) {
    String p = "";  if (s < 0) p = "-"; 
    else if (s > 0)
      {  if (show_plus) p = "+";
      else if (show_space) p = " ";
      }
    else
      {  if (fmt == 'o' && alternate && r.length() > 0 && r.charAt(0) != '0') p = "0";
      else if (fmt == 'x' && alternate) p = "0x";
      else if (fmt == 'X' && alternate) p = "0X";
      }
    int w = 0;
    if (leading_zeroes) 
      w = width;
    else if ((fmt == 'd' || fmt == 'i' || fmt == 'x' || fmt == 'X' || fmt == 'o') 
	     && precision > 0) w = precision;
      
    return p + repeat('0', w - p.length() - r.length()) + r;
  }
  private String fixed_format(double d) {
    String f = "";
    if (d > Long.MAX_VALUE) return exp_format(d);
    //here is the first change to the code (04/03/02)
    long l=(long) (d+=0.5*Math.pow(10D,-precision));
    //long l = (long)(precision == 0 ? d + 0.5 : d);
    f =f  + l;
    double fr = d - l; // fractional part
    if (fr >= 1 || fr < 0 && precision != 0) return exp_format(d);
    
    return f + frac_part(fr);
  }
  // precondition: 0 <= fr < 1
  private String frac_part(double fr) {
    String z = "";
    if (precision > 0){
    	double factor = 1;
      	String leading_zeroes = "";
      	for (int i = 1; i <= precision && factor <= Double.MAX_VALUE; i++) {
      		factor *= 10; 
			leading_zeroes = leading_zeroes + "0"; 
		}
     	//here is the second change to the code (04/03/02)
     	long l = (long) (factor * fr );
     	//long l = (long) (factor * fr + 0.5);
     	z = leading_zeroes + l;
      	z = z.substring(z.length() - precision, z.length());
    }

      
    if (precision > 0 || alternate) z = "." + z;
    if ((fmt == 'G' || fmt == 'g') && !alternate)
      // remove trailing zeroes and decimal point
      {  int t = z.length() - 1;
      while (t >= 0 && z.charAt(t) == '0') t--;
      if (t >= 0 && z.charAt(t) == '.') t--;
      z = z.substring(0, t + 1);
      }
    return z;
  }
  private String exp_format(double d) {
    String f = "";  int e = 0;
    double dd = d;
    double factor = 1;
    if (dd == 0) return "0";
    while (dd > 10) { e++; factor /= 10; dd = dd / 10; }
    while (dd < 1) { e--; factor *= 10; dd = dd * 10; }
    if ((fmt == 'g' || fmt == 'G') && e >= -4 && e < precision) 
      return fixed_format(d);
      
    d = d * factor;
    f = f + fixed_format(d);
      
    if (fmt == 'e' || fmt == 'g')
      f = f + "e";
    else
      f = f + "E";

    String p = "000";      
    if (e >= 0) 
      {  f = f + "+";
      p = p + e;
      }
    else
      {  f = f + "-";
      p = p + (-e);
      }
         
    return f + p.substring(p.length() - 3, p.length());
  }
  /** 
   * Formats the number following printf conventions.
   * Main limitation: Can only handle one format parameter at a time
   * Use multiple Format objects to format more than one number
   * @param s the format string following printf conventions
   * The string has a prefix, a format code and a suffix. The prefix and suffix
   * become part of the formatted output. The format code directs the
   * formatting of the (single) parameter to be formatted. The code has the
   * following structure
   * 
   * @exception IllegalArgumentException if bad format
   */
  public Format(String s) {
    width = 0;  precision = -1;
    pre = "";
    post = "";
    leading_zeroes = false;
    show_plus = false;
    alternate = false;
    show_space = false;
    left_align = false;
    fmt = ' '; 
      
    int state = 0; 
    int length = s.length();
    int parse_state = 0; 
    // 0 = prefix, 1 = flags, 2 = width, 3 = precision,
    // 4 = format, 5 = end
    int i = 0;
      
    while (parse_state == 0)
      {  if (i >= length) parse_state = 5;
      else if (s.charAt(i) == '%')
	{  if (i < length - 1)
	  {  if (s.charAt(i + 1) == '%')
	    {  pre = pre + '%';
	    i++;
	    }
	  else
	    parse_state = 1;
	  }
	else throw new java.lang.IllegalArgumentException();
	}
      else
	pre = pre + s.charAt(i);
      i++;
      }
    while (parse_state == 1)
      {  if (i >= length) parse_state = 5;
      else if (s.charAt(i) == ' ') show_space = true;
      else if (s.charAt(i) == '-') left_align = true; 
      else if (s.charAt(i) == '+') show_plus = true;
      else if (s.charAt(i) == '0') leading_zeroes = true;
      else if (s.charAt(i) == '#') alternate = true;
      else { parse_state = 2; i--; }
      i++;
      }      
    while (parse_state == 2)
      {  if (i >= length) parse_state = 5;
      else if ('0' <= s.charAt(i) && s.charAt(i) <= '9')
	{  width = width * 10 + s.charAt(i) - '0';
	i++;
	}
      else if (s.charAt(i) == '.')
	{  parse_state = 3;
	precision = 0;
	i++;
	}
      else 
	parse_state = 4;            
      }
    while (parse_state == 3)
      {  if (i >= length) parse_state = 5;
      else if ('0' <= s.charAt(i) && s.charAt(i) <= '9')
	{  precision = precision * 10 + s.charAt(i) - '0';
	i++;
	}
      else 
	parse_state = 4;                  
      }
    if (parse_state == 4) 
      {  if (i >= length) parse_state = 5;
      else fmt = s.charAt(i);
      i++;
      }
    if (i < length)
      post = s.substring(i, length);
  }
  /** 
   * prints a formatted number following printf conventions
   * @param s a PrintStream
   * @param fmt the format string
   * @param x the double to print
   */
  public static void print(java.io.PrintStream s,String fmt,double x) {
    s.print(new Format(fmt).form(x));
  }
  /** 
   * prints a formatted number following printf conventions
   * @param s a PrintStream
   * @param fmt the format string
   * @param x the long to print
   */
  public static void print(java.io.PrintStream s,String fmt,long x) {
    s.print(new Format(fmt).form(x));
  }
  /** 
   * prints a formatted number following printf conventions
   * @param s a PrintStream
   * @param fmt the format string
   * @param x the character to 
   */
  public static void print(java.io.PrintStream s,String fmt,char x) {
    s.print(new Format(fmt).form(x));
  }
  /** 
   * prints a formatted number following printf conventions
   * @param s a PrintStream, fmt the format string
   * @param x a string that represents the digits to print
   */
  public static void print(java.io.PrintStream s,String fmt,String x) {
    s.print(new Format(fmt).form(x));
  }
  /** 
   * Converts a string of digits (decimal, octal or hex) to an integer
   * @param s a string
   * @return the numeric value of the prefix of s representing a base 10 integer
   */
  public static int atoi(String s) {
    return (int)atol(s);
  }
  /** 
   * Converts a string of digits (decimal, octal or hex) to a long integer
   * @param s a string
   * @return the numeric value of the prefix of s representing a base 10 integer
   */
  public static long atol(String s) {
    int i = 0;
    while (i < s.length() && Character.isWhitespace(s.charAt(i))) i++;
    if (i < s.length() && s.charAt(i) == '0')
      {  if (i + 1 < s.length() && (s.charAt(i + 1) == 'x' || s.charAt(i + 1) == 'X'))
	return parseLong(s.substring(i + 2), 16);
      else return parseLong(s, 8);
      }
    else return parseLong(s, 10);
  }
  /**
   * Computes the format based on desired prescision and 
   * minimum, maximum values.
   *
   * @param min minimum value
   * @param max maximum value
   * @param pres prescision
   */
  public static String computeFormat(double min,double max,int pres) {
    double dx, xx;
    int ip, id, ib;
    String frmt;
          
    dx = Math.abs(max - min);
    xx = Math.abs(max);
    if(xx < Math.abs(min)) xx = Math.abs(min);
    if(pres >= 0 && (xx >= 1000000.0f || xx < 0.001f)) {
      id = pres -1;
      if(id < 0) id=0;
      frmt = "%" + "." + id + "e";
    } else {
      ip = Math.abs(pres);
      id = ip - (int)(log10(dx) + 0.5);
      if(id < 0) id = 0;
      frmt = "%" + "." + id + "f";
    }
    return frmt;
  }
  static final double log10(double x) {
    return 0.4342944819*Math.log(x);
  }
  /** 
   * Converts a string of digits to an double
   * @param s a string
   */
  public static double atof(String s) {
    int i = 0;  int sign = 1;
    double r = 0; // integer part
    double f = 0; // fractional part
    double p = 1; // exponent of fractional part
    int state = 0; // 0 = int part, 1 = frac part
      
    while (i < s.length() && Character.isWhitespace(s.charAt(i))) i++;
    if (i < s.length() && s.charAt(i) == '-') { sign = -1; i++; }
    else if (i < s.length() && s.charAt(i) == '+') { i++; }
    while (i < s.length())
      {  char ch = s.charAt(i);
      if ('0' <= ch && ch <= '9')
	{  if (state == 0)
	  r = r * 10 + ch - '0';
	else if (state == 1)
	  {  p = p / 10;
	  r = r + p * (ch - '0');
	  }
	}
      else if (ch == '.') 
	{  if (state == 0) state = 1; 
	else return sign * r;
	}
      else if (ch == 'e' || ch == 'E')
	{  long e = (int)parseLong(s.substring(i + 1), 10);
	return sign * r * Math.pow(10, e);
	}
      else return sign * r;
      i++;
      }
    return sign * r;
  }
  /** 
   * Formats a double into a string (like sprintf in C)
   * @param x the number to format
   * @return the formatted string 
   * @exception IllegalArgumentException if bad argument
   */
  public String form(double x) {
    String r;  if (precision < 0) precision = 6;
    int s = 1;
    if (x < 0) { x = -x; s = -1; }
    if (fmt == 'f'){
      r = fixed_format(x);
    	}
    else if (fmt == 'e' || fmt == 'E' || fmt == 'g' || fmt == 'G')
      r = exp_format(x);
    else throw new java.lang.IllegalArgumentException();
    return pad(sign(s, r));
  }
  /** 
   * Formats a long integer into a string (like sprintf in C)
   * @param x the number to format
   * @return the formatted string 
   */
  public String form(long x) {
    String r;   int s = 0;
    if (fmt == 'd' || fmt == 'i')
      {  s = 1;
      if (x < 0) { x = -x; s = -1; }
      r = "" + x;
      }
    else if (fmt == 'o')
      r = convert(x, 3, 7, "01234567");
    else if (fmt == 'x')
      r = convert(x, 4, 15, "0123456789abcdef");
    else if (fmt == 'X')
      r = convert(x, 4, 15, "0123456789ABCDEF");
    else throw new java.lang.IllegalArgumentException();
         
    return pad(sign(s, r));
  }
  /** 
   * Formats a character into a string (like sprintf in C)
   * @param x the value to format
   * @return the formatted string 
   */
  public String form(char c) {
    if (fmt != 'c')    throw new java.lang.IllegalArgumentException();

    String r = "" + c;
    return pad(r);
  }
  /** 
   * Formats a string into a larger string (like sprintf in C)
   * @param x the value to format
   * @return the formatted string 
   */
  public String form(String s) {
    if (fmt != 's')    throw new java.lang.IllegalArgumentException();
    if (precision >= 0) s = s.substring(0, precision);
    return pad(s);
  }
}

 

Ads help maintain this website.