From 935d2596c13371bb745d921dbcb9f05b0c11a010 Mon Sep 17 00:00:00 2001
From: Kenneth Russel
- * A control string is a Java string that contains a
- * control specification. The control specification
- * starts at the first percent sign (%) in the string,
- * provided that this percent sign
- *
- *
- *
- * A control specification usually takes the form: - *
% ['-+ #0]* [0..9]* { . [0..9]* }+ - * { [hlL] }+ [idfgGoxXeEcs] - *- * There are variants of this basic form that are - * discussed below. - *
- * The format is composed of zero or more directives - * defined as follows: - *
- * The results are undefined if there are insufficient - * arguments for the format. Usually an unchecked - * exception will be thrown. If the format is - * exhausted while arguments remain, the excess - * arguments are evaluated but are otherwise ignored. - * In format strings containing the % form of - * conversion specifications, each argument in the - * argument list is used exactly once.
- *
- * Conversions can be applied to the n
th
- * argument after the format in the argument list,
- * rather than to the next unused argument. In this
- * case, the conversion characer % is replaced by the
- * sequence %n
$, where n
is
- * a decimal integer giving the position of the
- * argument in the argument list.
- * In format strings containing the %n
$
- * form of conversion specifications, each argument
- * in the argument list is used exactly once.
- * The following table lists escape sequences and - * associated actions on display devices capable of - * the action. - *
Sequence | - *Name | - *Description |
---|---|---|
\\ | backlash | None. - * |
\a | alert | Attempts to alert - * the user through audible or visible - * notification. - * |
\b | backspace | Moves the - * printing position to one column before - * the current position, unless the - * current position is the start of a line. - * |
\f | form-feed | Moves the - * printing position to the initial - * printing position of the next logical - * page. - * |
\n | newline | Moves the - * printing position to the start of the - * next line. - * |
\r | carriage-return | Moves - * the printing position to the start of - * the current line. - * |
\t | tab | Moves the printing - * position to the next implementation- - * defined horizontal tab position. - * |
\v | vertical-tab | Moves the - * printing position to the start of the - * next implementation-defined vertical - * tab position. - * |
- * Each conversion specification is introduced by - * the percent sign character (%). After the character - * %, the following appear in sequence:
- *- * Zero or more flags (in any order), which modify the - * meaning of the conversion specification.
- *- * An optional minimum field width. If the converted - * value has fewer characters than the field width, it - * will be padded with spaces by default on the left; - * t will be padded on the right, if the left- - * adjustment flag (-), described below, is given to - * the field width. The field width takes the form - * of a decimal integer. If the conversion character - * is s, the field width is the the minimum number of - * characters to be printed.
- *- * An optional precision that gives the minumum number - * of digits to appear for the d, i, o, x or X - * conversions (the field is padded with leading - * zeros); the number of digits to appear after the - * radix character for the e, E, and f conversions, - * the maximum number of significant digits for the g - * and G conversions; or the maximum number of - * characters to be written from a string is s and S - * conversions. The precision takes the form of an - * optional decimal digit string, where a null digit - * string is treated as 0. If a precision appears - * with a c conversion character the precision is - * ignored. - *
- *- * An optional h specifies that a following d, i, o, - * x, or X conversion character applies to a type - * short argument (the argument will be promoted - * according to the integral promotions and its value - * converted to type short before printing).
- *- * An optional l (ell) specifies that a following - * d, i, o, x, or X conversion character applies to a - * type long argument.
- *- * A field width or precision may be indicated by an - * asterisk (*) instead of a digit string. In this - * case, an integer argument supplised the field width - * precision. The argument that is actually converted - * is not fetched until the conversion letter is seen, - * so the the arguments specifying field width or - * precision must appear before the argument (if any) - * to be converted. If the precision argument is - * negative, it will be changed to zero. A negative - * field width argument is taken as a - flag, followed - * by a positive field width.
- *
- * In format strings containing the %n
$
- * form of a conversion specification, a field width
- * or precision may be indicated by the sequence
- * *m
$, where m is a decimal integer
- * giving the position in the argument list (after the
- * format argument) of an integer argument containing
- * the field width or precision.
- * The format can contain either numbered argument
- * specifications (that is, %n
$ and
- * *m
$), or unnumbered argument
- * specifications (that is % and *), but normally not
- * both. The only exception to this is that %% can
- * be mixed with the %n
$ form. The
- * results of mixing numbered and unnumbered argument
- * specifications in a format string are undefined.
- * The flags and their meanings are:
- *- * Each conversion character results in fetching zero - * or more arguments. The results are undefined if - * there are insufficient arguments for the format. - * Usually, an unchecked exception will be thrown. - * If the format is exhausted while arguments remain, - * the excess arguments are ignored.
- * - *- * The conversion characters and their meanings are: - *
- *- * If a conversion specification does not match one of - * the above forms, an IllegalArgumentException is - * thrown and the instance of PrintfFormat is not - * created.
- *- * If a floating point value is the internal - * representation for infinity, the output is - * [+]Infinity, where Infinity is either Infinity or - * Inf, depending on the desired output string length. - * Printing of the sign follows the rules described - * above.
- *- * If a floating point value is the internal - * representation for "not-a-number," the output is - * [+]NaN. Printing of the sign follows the rules - * described above.
- *- * In no case does a non-existent or small field width - * cause truncation of a field; if the result of a - * conversion is wider than the field width, the field - * is simply expanded to contain the conversion result. - *
- *- * The behavior is like printf. One exception is that - * the minimum number of exponent digits is 3 instead - * of 2 for e and E formats when the optional L is used - * before the e, E, g, or G conversion character. The - * optional L does not imply conversion to a long long - * double.
- *- * The biggest divergence from the C printf - * specification is in the use of 16 bit characters. - * This allows the handling of characters beyond the - * small ASCII character set and allows the utility to - * interoperate correctly with the rest of the Java - * runtime environment.
- *- * Omissions from the C printf specification are - * numerous. All the known omissions are present - * because Java never uses bytes to represent - * characters and does not have pointers:
- *- * Most of this specification is quoted from the Unix - * man page for the sprintf utility.
- * - * @author Allan Jacobs - * @version 1 - * Release 1: Initial release. - * Release 2: Asterisk field widths and precisions - * %n$ and *m$ - * Bug fixes - * g format fix (2 digits in e form corrupt) - * rounding in f format implemented - * round up when digit not printed is 5 - * formatting of -0.0f - * round up/down when last digits are 50000... - */ -public class PrintfFormat { - /** - * Constructs an array of control specifications - * possibly preceded, separated, or followed by - * ordinary strings. Control strings begin with - * unpaired percent signs. A pair of successive - * percent signs designates a single percent sign in - * the format. - * @param fmtArg Control string. - * @exception IllegalArgumentException if the control - * string is null, zero length, or otherwise - * malformed. - */ - public PrintfFormat(String fmtArg) - throws IllegalArgumentException { - this(Locale.getDefault(),fmtArg); - } - /** - * Constructs an array of control specifications - * possibly preceded, separated, or followed by - * ordinary strings. Control strings begin with - * unpaired percent signs. A pair of successive - * percent signs designates a single percent sign in - * the format. - * @param fmtArg Control string. - * @exception IllegalArgumentException if the control - * string is null, zero length, or otherwise - * malformed. - */ - public PrintfFormat(Locale locale,String fmtArg) - throws IllegalArgumentException { - dfs = new DecimalFormatSymbols(locale); - int ePos=0; - ConversionSpecification sFmt=null; - String unCS = this.nonControl(fmtArg,0); - if (unCS!=null) { - sFmt = new ConversionSpecification(); - sFmt.setLiteral(unCS); - vFmt.addElement(sFmt); - } - while(cPos!=-1 && cPoss
, the next unpaired
- * percent sign, or at the end of the String if the
- * last character is a percent sign.
- * @param s Control string.
- * @param start Position in the string
- * s
to begin looking for the start
- * of a control string.
- * @return the substring from the start position
- * to the beginning of the control string.
- */
- private String nonControl(String s,int start) {
- String ret="";
- cPos=s.indexOf("%",start);
- if (cPos==-1) cPos=s.length();
- return s.substring(start,cPos);
- }
- /**
- * Format an array of objects. Byte, Short,
- * Integer, Long, Float, Double, and Character
- * arguments are treated as wrappers for primitive
- * types.
- * @param o The array of objects to format.
- * @return The formatted String.
- */
- public String sprintf(Object[] o) {
- Enumeration e = vFmt.elements();
- ConversionSpecification cs = null;
- char c = 0;
- int i=0;
- StringBuffer sb=new StringBuffer();
- while (e.hasMoreElements()) {
- cs = (ConversionSpecification)
- e.nextElement();
- c = cs.getConversionCharacter();
- if (c=='\0') sb.append(cs.getLiteral());
- else if (c=='%') sb.append("%");
- else {
- if (cs.isPositionalSpecification()) {
- i=cs.getArgumentPosition()-1;
- if (cs.isPositionalFieldWidth()) {
- int ifw=cs.getArgumentPositionForFieldWidth()-1;
- cs.setFieldWidthWithArg(((Integer)o[ifw]).intValue());
- }
- if (cs.isPositionalPrecision()) {
- int ipr=cs.getArgumentPositionForPrecision()-1;
- cs.setPrecisionWithArg(((Integer)o[ipr]).intValue());
- }
- }
- else {
- if (cs.isVariableFieldWidth()) {
- cs.setFieldWidthWithArg(((Integer)o[i]).intValue());
- i++;
- }
- if (cs.isVariablePrecision()) {
- cs.setPrecisionWithArg(((Integer)o[i]).intValue());
- i++;
- }
- }
- if (o[i] instanceof Byte)
- sb.append(cs.internalsprintf(
- ((Byte)o[i]).byteValue()));
- else if (o[i] instanceof Short)
- sb.append(cs.internalsprintf(
- ((Short)o[i]).shortValue()));
- else if (o[i] instanceof Integer)
- sb.append(cs.internalsprintf(
- ((Integer)o[i]).intValue()));
- else if (o[i] instanceof Long)
- sb.append(cs.internalsprintf(
- ((Long)o[i]).longValue()));
- else if (o[i] instanceof Float)
- sb.append(cs.internalsprintf(
- ((Float)o[i]).floatValue()));
- else if (o[i] instanceof Double)
- sb.append(cs.internalsprintf(
- ((Double)o[i]).doubleValue()));
- else if (o[i] instanceof Character)
- sb.append(cs.internalsprintf(
- ((Character)o[i]).charValue()));
- else if (o[i] instanceof String)
- sb.append(cs.internalsprintf(
- (String)o[i]));
- else
- sb.append(cs.internalsprintf(
- o[i]));
- if (!cs.isPositionalSpecification())
- i++;
- }
- }
- return sb.toString();
- }
- /**
- * Format nothing. Just use the control string.
- * @return the formatted String.
- */
- public String sprintf() {
- Enumeration e = vFmt.elements();
- ConversionSpecification cs = null;
- char c = 0;
- StringBuffer sb=new StringBuffer();
- while (e.hasMoreElements()) {
- cs = (ConversionSpecification)
- e.nextElement();
- c = cs.getConversionCharacter();
- if (c=='\0') sb.append(cs.getLiteral());
- else if (c=='%') sb.append("%");
- }
- return sb.toString();
- }
- /**
- * Format an int.
- * @param x The int to format.
- * @return The formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is f, e, E, g, G, s,
- * or S.
- */
- public String sprintf(int x)
- throws IllegalArgumentException {
- Enumeration e = vFmt.elements();
- ConversionSpecification cs = null;
- char c = 0;
- StringBuffer sb=new StringBuffer();
- while (e.hasMoreElements()) {
- cs = (ConversionSpecification)
- e.nextElement();
- c = cs.getConversionCharacter();
- if (c=='\0') sb.append(cs.getLiteral());
- else if (c=='%') sb.append("%");
- else sb.append(cs.internalsprintf(x));
- }
- return sb.toString();
- }
- /**
- * Format an long.
- * @param x The long to format.
- * @return The formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is f, e, E, g, G, s,
- * or S.
- */
- public String sprintf(long x)
- throws IllegalArgumentException {
- Enumeration e = vFmt.elements();
- ConversionSpecification cs = null;
- char c = 0;
- StringBuffer sb=new StringBuffer();
- while (e.hasMoreElements()) {
- cs = (ConversionSpecification)
- e.nextElement();
- c = cs.getConversionCharacter();
- if (c=='\0') sb.append(cs.getLiteral());
- else if (c=='%') sb.append("%");
- else sb.append(cs.internalsprintf(x));
- }
- return sb.toString();
- }
- /**
- * Format a double.
- * @param x The double to format.
- * @return The formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is c, C, s, S,
- * d, d, x, X, or o.
- */
- public String sprintf(double x)
- throws IllegalArgumentException {
- Enumeration e = vFmt.elements();
- ConversionSpecification cs = null;
- char c = 0;
- StringBuffer sb=new StringBuffer();
- while (e.hasMoreElements()) {
- cs = (ConversionSpecification)
- e.nextElement();
- c = cs.getConversionCharacter();
- if (c=='\0') sb.append(cs.getLiteral());
- else if (c=='%') sb.append("%");
- else sb.append(cs.internalsprintf(x));
- }
- return sb.toString();
- }
- /**
- * Format a String.
- * @param x The String to format.
- * @return The formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is neither s nor S.
- */
- public String sprintf(String x)
- throws IllegalArgumentException {
- Enumeration e = vFmt.elements();
- ConversionSpecification cs = null;
- char c = 0;
- StringBuffer sb=new StringBuffer();
- while (e.hasMoreElements()) {
- cs = (ConversionSpecification)
- e.nextElement();
- c = cs.getConversionCharacter();
- if (c=='\0') sb.append(cs.getLiteral());
- else if (c=='%') sb.append("%");
- else sb.append(cs.internalsprintf(x));
- }
- return sb.toString();
- }
- /**
- * Format an Object. Convert wrapper types to
- * their primitive equivalents and call the
- * appropriate internal formatting method. Convert
- * Strings using an internal formatting method for
- * Strings. Otherwise use the default formatter
- * (use toString).
- * @param x the Object to format.
- * @return the formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is inappropriate for
- * formatting an unwrapped value.
- */
- public String sprintf(Object x)
- throws IllegalArgumentException {
- Enumeration e = vFmt.elements();
- ConversionSpecification cs = null;
- char c = 0;
- StringBuffer sb=new StringBuffer();
- while (e.hasMoreElements()) {
- cs = (ConversionSpecification)
- e.nextElement();
- c = cs.getConversionCharacter();
- if (c=='\0') sb.append(cs.getLiteral());
- else if (c=='%') sb.append("%");
- else {
- if (x instanceof Byte)
- sb.append(cs.internalsprintf(
- ((Byte)x).byteValue()));
- else if (x instanceof Short)
- sb.append(cs.internalsprintf(
- ((Short)x).shortValue()));
- else if (x instanceof Integer)
- sb.append(cs.internalsprintf(
- ((Integer)x).intValue()));
- else if (x instanceof Long)
- sb.append(cs.internalsprintf(
- ((Long)x).longValue()));
- else if (x instanceof Float)
- sb.append(cs.internalsprintf(
- ((Float)x).floatValue()));
- else if (x instanceof Double)
- sb.append(cs.internalsprintf(
- ((Double)x).doubleValue()));
- else if (x instanceof Character)
- sb.append(cs.internalsprintf(
- ((Character)x).charValue()));
- else if (x instanceof String)
- sb.append(cs.internalsprintf(
- (String)x));
- else
- sb.append(cs.internalsprintf(x));
- }
- }
- return sb.toString();
- }
- /**
- *- * ConversionSpecification allows the formatting of - * a single primitive or object embedded within a - * string. The formatting is controlled by a - * format string. Only one Java primitive or - * object can be formatted at a time. - *
- * A format string is a Java string that contains - * a control string. The control string starts at - * the first percent sign (%) in the string, - * provided that this percent sign - *
- * A control string takes the form: - *
% ['-+ #0]* [0..9]* { . [0..9]* }+ - * { [hlL] }+ [idfgGoxXeEcs] - *- *
- * The behavior is like printf. One (hopefully the
- * only) exception is that the minimum number of
- * exponent digits is 3 instead of 2 for e and E
- * formats when the optional L is used before the
- * e, E, g, or G conversion character. The
- * optional L does not imply conversion to a long
- * long double.
- */
- private class ConversionSpecification {
- /**
- * Constructor. Used to prepare an instance
- * to hold a literal, not a control string.
- */
- ConversionSpecification() { }
- /**
- * Constructor for a conversion specification.
- * The argument must begin with a % and end
- * with the conversion character for the
- * conversion specification.
- * @param fmtArg String specifying the
- * conversion specification.
- * @exception IllegalArgumentException if the
- * input string is null, zero length, or
- * otherwise malformed.
- */
- ConversionSpecification(String fmtArg)
- throws IllegalArgumentException {
- if (fmtArg==null)
- throw new NullPointerException();
- if (fmtArg.length()==0)
- throw new IllegalArgumentException(
- "Control strings must have positive"+
- " lengths.");
- if (fmtArg.charAt(0)=='%') {
- fmt = fmtArg;
- pos=1;
- setArgPosition();
- setFlagCharacters();
- setFieldWidth();
- setPrecision();
- setOptionalHL();
- if (setConversionCharacter()) {
- if (pos==fmtArg.length()) {
- if(leadingZeros&&leftJustify)
- leadingZeros=false;
- if(precisionSet&&leadingZeros){
- if(conversionCharacter=='d'
- ||conversionCharacter=='i'
- ||conversionCharacter=='o'
- ||conversionCharacter=='x')
- {
- leadingZeros=false;
- }
- }
- }
- else
- throw new IllegalArgumentException(
- "Malformed conversion specification="+
- fmtArg);
- }
- else
- throw new IllegalArgumentException(
- "Malformed conversion specification="+
- fmtArg);
- }
- else
- throw new IllegalArgumentException(
- "Control strings must begin with %.");
- }
- /**
- * Set the String for this instance.
- * @param s the String to store.
- */
- void setLiteral(String s) {
- fmt = s;
- }
- /**
- * Get the String for this instance. Translate
- * any escape sequences.
- *
- * @return s the stored String.
- */
- String getLiteral() {
- StringBuffer sb=new StringBuffer();
- int i=0;
- while (ifalse
.
- */
- boolean isVariableFieldWidth() {
- return variableFieldWidth;
- }
- /**
- * Set the field width with an argument. A
- * negative field width is taken as a - flag
- * followed by a positive field width.
- * @param fw the field width.
- */
- void setFieldWidthWithArg(int fw) {
- if (fw<0) leftJustify = true;
- fieldWidthSet = true;
- fieldWidth = Math.abs(fw);
- }
- /**
- * Check whether the specifier has a variable
- * precision that is going to be set by an
- * argument.
- * @return true
if the conversion
- * uses an * precision; otherwise
- * false
.
- */
- boolean isVariablePrecision() {
- return variablePrecision;
- }
- /**
- * Set the precision with an argument. A
- * negative precision will be changed to zero.
- * @param pr the precision.
- */
- void setPrecisionWithArg(int pr) {
- precisionSet = true;
- precision = Math.max(pr,0);
- }
- /**
- * Format an int argument using this conversion
- * specification.
- * @param s the int to format.
- * @return the formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is f, e, E, g, or G.
- */
- String internalsprintf(int s)
- throws IllegalArgumentException {
- String s2 = "";
- switch(conversionCharacter) {
- case 'd':
- case 'i':
- if (optionalh)
- s2 = printDFormat((short)s);
- else if (optionall)
- s2 = printDFormat((long)s);
- else
- s2 = printDFormat(s);
- break;
- case 'x':
- case 'X':
- if (optionalh)
- s2 = printXFormat((short)s);
- else if (optionall)
- s2 = printXFormat((long)s);
- else
- s2 = printXFormat(s);
- break;
- case 'o':
- if (optionalh)
- s2 = printOFormat((short)s);
- else if (optionall)
- s2 = printOFormat((long)s);
- else
- s2 = printOFormat(s);
- break;
- case 'c':
- case 'C':
- s2 = printCFormat((char)s);
- break;
- default:
- throw new IllegalArgumentException(
- "Cannot format a int with a format using a "+
- conversionCharacter+
- " conversion character.");
- }
- return s2;
- }
- /**
- * Format a long argument using this conversion
- * specification.
- * @param s the long to format.
- * @return the formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is f, e, E, g, or G.
- */
- String internalsprintf(long s)
- throws IllegalArgumentException {
- String s2 = "";
- switch(conversionCharacter) {
- case 'd':
- case 'i':
- if (optionalh)
- s2 = printDFormat((short)s);
- else if (optionall)
- s2 = printDFormat(s);
- else
- s2 = printDFormat((int)s);
- break;
- case 'x':
- case 'X':
- if (optionalh)
- s2 = printXFormat((short)s);
- else if (optionall)
- s2 = printXFormat(s);
- else
- s2 = printXFormat((int)s);
- break;
- case 'o':
- if (optionalh)
- s2 = printOFormat((short)s);
- else if (optionall)
- s2 = printOFormat(s);
- else
- s2 = printOFormat((int)s);
- break;
- case 'c':
- case 'C':
- s2 = printCFormat((char)s);
- break;
- default:
- throw new IllegalArgumentException(
- "Cannot format a long with a format using a "+
- conversionCharacter+" conversion character.");
- }
- return s2;
- }
- /**
- * Format a double argument using this conversion
- * specification.
- * @param s the double to format.
- * @return the formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is c, C, s, S, i, d,
- * x, X, or o.
- */
- String internalsprintf(double s)
- throws IllegalArgumentException {
- String s2 = "";
- switch(conversionCharacter) {
- case 'f':
- s2 = printFFormat(s);
- break;
- case 'E':
- case 'e':
- s2 = printEFormat(s);
- break;
- case 'G':
- case 'g':
- s2 = printGFormat(s);
- break;
- default:
- throw new IllegalArgumentException("Cannot "+
- "format a double with a format using a "+
- conversionCharacter+" conversion character.");
- }
- return s2;
- }
- /**
- * Format a String argument using this conversion
- * specification.
- * @param s the String to format.
- * @return the formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is neither s nor S.
- */
- String internalsprintf(String s)
- throws IllegalArgumentException {
- String s2 = "";
- if(conversionCharacter=='s'
- || conversionCharacter=='S')
- s2 = printSFormat(s);
- else
- throw new IllegalArgumentException("Cannot "+
- "format a String with a format using a "+
- conversionCharacter+" conversion character.");
- return s2;
- }
- /**
- * Format an Object argument using this conversion
- * specification.
- * @param s the Object to format.
- * @return the formatted String.
- * @exception IllegalArgumentException if the
- * conversion character is neither s nor S.
- */
- String internalsprintf(Object s) {
- String s2 = "";
- if(conversionCharacter=='s'
- || conversionCharacter=='S')
- s2 = printSFormat(s.toString());
- else
- throw new IllegalArgumentException(
- "Cannot format a String with a format using"+
- " a "+conversionCharacter+
- " conversion character.");
- return s2;
- }
- /**
- * For f format, the flag character '-', means that
- * the output should be left justified within the
- * field. The default is to pad with blanks on the
- * left. '+' character means that the conversion
- * will always begin with a sign (+ or -). The
- * blank flag character means that a non-negative
- * input will be preceded with a blank. If both
- * a '+' and a ' ' are specified, the blank flag
- * is ignored. The '0' flag character implies that
- * padding to the field width will be done with
- * zeros instead of blanks.
- *
- * The field width is treated as the minimum number
- * of characters to be printed. The default is to
- * add no padding. Padding is with blanks by
- * default.
- *
- * The precision, if set, is the number of digits
- * to appear after the radix character. Padding is
- * with trailing 0s.
- */
- private char[] fFormatDigits(double x) {
- // int defaultDigits=6;
- String sx,sxOut;
- int i,j,k;
- int n1In,n2In;
- int expon=0;
- boolean minusSign=false;
- if (x>0.0)
- sx = Double.toString(x);
- else if (x<0.0) {
- sx = Double.toString(-x);
- minusSign=true;
- }
- else {
- sx = Double.toString(x);
- if (sx.charAt(0)=='-') {
- minusSign=true;
- sx=sx.substring(1);
- }
- }
- int ePos = sx.indexOf('E');
- int rPos = sx.indexOf('.');
- if (rPos!=-1) n1In=rPos;
- else if (ePos!=-1) n1In=ePos;
- else n1In=sx.length();
- if (rPos!=-1) {
- if (ePos!=-1) n2In = ePos-rPos-1;
- else n2In = sx.length()-rPos-1;
- }
- else
- n2In = 0;
- if (ePos!=-1) {
- int ie=ePos+1;
- expon=0;
- if (sx.charAt(ie)=='-') {
- for (++ie; ietrue
if the carry forces
- * a round that will change the print still
- * more
- */
- private boolean startSymbolicCarry(
- char[] ca,int cLast,int cFirst) {
- boolean carry=true;
- for (int i=cLast; carry && i>=cFirst; i--) {
- carry = false;
- switch(ca[i]) {
- case '0': ca[i]='1'; break;
- case '1': ca[i]='2'; break;
- case '2': ca[i]='3'; break;
- case '3': ca[i]='4'; break;
- case '4': ca[i]='5'; break;
- case '5': ca[i]='6'; break;
- case '6': ca[i]='7'; break;
- case '7': ca[i]='8'; break;
- case '8': ca[i]='9'; break;
- case '9': ca[i]='0'; carry=true; break;
- }
- }
- return carry;
- }
- /**
- * An intermediate routine on the way to creating
- * an e format String. The method decides whether
- * the input double value is an infinity,
- * not-a-number, or a finite double and formats
- * each type of input appropriately.
- * @param x the double value to be formatted.
- * @param eChar an 'e' or 'E' to use in the
- * converted double value.
- * @return the converted double value.
- */
- private String eFormatString(double x,char eChar) {
- boolean noDigits=false;
- char[] ca4,ca5;
- if (Double.isInfinite(x)) {
- if (x==Double.POSITIVE_INFINITY) {
- if (leadingSign) ca4 = "+Inf".toCharArray();
- else if (leadingSpace)
- ca4 = " Inf".toCharArray();
- else ca4 = "Inf".toCharArray();
- }
- else
- ca4 = "-Inf".toCharArray();
- noDigits = true;
- }
- else if (Double.isNaN(x)) {
- if (leadingSign) ca4 = "+NaN".toCharArray();
- else if (leadingSpace)
- ca4 = " NaN".toCharArray();
- else ca4 = "NaN".toCharArray();
- noDigits = true;
- }
- else
- ca4 = eFormatDigits(x,eChar);
- ca5 = applyFloatPadding(ca4,false);
- return new String(ca5);
- }
- /**
- * Apply zero or blank, left or right padding.
- * @param ca4 array of characters before padding is
- * finished
- * @param noDigits NaN or signed Inf
- * @return a padded array of characters
- */
- private char[] applyFloatPadding(
- char[] ca4,boolean noDigits) {
- char[] ca5 = ca4;
- if (fieldWidthSet) {
- int i,j,nBlanks;
- if (leftJustify) {
- nBlanks = fieldWidth-ca4.length;
- if (nBlanks > 0) {
- ca5 = new char[ca4.length+nBlanks];
- for (i=0; ifalse
otherwise.
- */
- private boolean setConversionCharacter() {
- /* idfgGoxXeEcs */
- boolean ret = false;
- conversionCharacter='\0';
- if (pos < fmt.length()) {
- char c = fmt.charAt(pos);
- if (c=='i'||c=='d'||c=='f'||c=='g'||c=='G'
- || c=='o' || c=='x' || c=='X' || c=='e'
- || c=='E' || c=='c' || c=='s' || c=='%') {
- conversionCharacter = c;
- pos++;
- ret = true;
- }
- }
- return ret;
- }
- /**
- * Check for an h, l, or L in a format. An L is
- * used to control the minimum number of digits
- * in an exponent when using floating point
- * formats. An l or h is used to control
- * conversion of the input to a long or short,
- * respectively, before formatting. If any of
- * these is present, store them.
- */
- private void setOptionalHL() {
- optionalh=false;
- optionall=false;
- optionalL=false;
- if (pos < fmt.length()) {
- char c = fmt.charAt(pos);
- if (c=='h') { optionalh=true; pos++; }
- else if (c=='l') { optionall=true; pos++; }
- else if (c=='L') { optionalL=true; pos++; }
- }
- }
- /**
- * Set the precision.
- */
- private void setPrecision() {
- int firstPos = pos;
- precisionSet = false;
- if (pos