Web Development and Design | Tutorial for Java, PHP, HTML, Javascript: java-string-format-double

Web Development and Design | Tutorial for Java, PHP, HTML, Javascript: java-string-format-double
Showing posts with label java-string-format-double. Show all posts
Showing posts with label java-string-format-double. Show all posts

Java Formatting Numbers

Java Formatting Numbers


Problem

You need to format numbers.

Solution

Use a NumberFormat subclass.

Java has not traditionally provided a C-style printf /scanf functions because they tend
to mix together formatting and input/output in a very inflexible way. Programs using
printf /scanf can be very hard to internationalize, for example.

Java has an entire package, java.text , full of formatting routines as general and flexi-
ble as anything you might imagine. As with printf, it has an involved formatting lan-
guage, described in the Javadoc page. Consider the presentation of long numbers. In
North America, the number one thousand twenty-four and a quarter is written
1,024.25, in most of Europe it is 1 024,25, and in some other part of the world it
might be written 1.024,25. Not to mention how currencies and percentages are for-
matted! Trying to keep track of this yourself would drive the average small software
shop around the bend rather quickly.

Fortunately, the java.text package includes a Locale class, and, furthermore, the
Java runtime automatically sets a default Locale object based on the user’s environ-
ment; e.g., on the Macintosh and Windows, the user’s preferences; on Unix, the
user’s environment variables. (To provide a nondefault locale, see Recipe 15.8.) To
provide formatters customized for numbers, currencies, and percentages, the
NumberFormat class has static factory methods that normally return a DecimalFormat
with the correct pattern already instantiated. A DecimalFormat object appropriate to
the user’s locale can be obtained from the factory method NumberFormat.
getInstance( ) and manipulated using set methods. Surprisingly, the method
setMinimumIntegerDigits( ) turns out to be the easy way to generate a number for-
mat with leading zeros. Here is an example:

import java.text.*;
import java.util.*;
/*
* Format a number our way and the default way.
*/
public class NumFormat2 {
/** A number to format */
public static final double data[] = {
0, 1, 22d/7, 100.2345678
};
/** The main (and only) method in this class. */
public static void main(String av[]) {
// Get a format instance
NumberFormat form = NumberFormat.getInstance( );
// Set it to look like 999.99[99]
form.setMinimumIntegerDigits(3);
form.setMinimumFractionDigits(2);
form.setMaximumFractionDigits(4);
// Now print using it.
for (int i=0; i<data.length; i++)
System.out.println(data[i] + "\tformats as " +
form.format(data[i]));
}
}

This prints the contents of the array using the NumberFormat instance form :

$ java NumFormat2
0.0
formats as 000.00
1.0
formats as 001.00
3.142857142857143
formats as 003.1429
100.2345678
formats as 100.2346
$

You can also construct a DecimalFormat with a particular pattern or change the pat- tern dynamically using applyPattern( ) . Some of the more common pattern charac- ters are shown in Table
Table DecimalFormat pattern characters

Character                                                                            Meaning

#                                                                    Numeric digit (leading zeros suppressed)

0                                                                      Numeric digit (leading zeros provided)

.                                                                  Locale-specific decimal separator (decimal point)

,                                                              Locale-specific grouping separator (comma in English)

-                                                              Locale-specific negative indicator (minus sign)

%                                                             Shows the value as a percentage

;                                    Separates two formats: the first for positive and the second for negative values

'                                             Escapes one of the above characters so it appears
                                                                   Anything else Appears as itself


The NumFormatTest program uses one DecimalFormat to print a number with only two
decimal places and a second to format the number according to the default locale:

// NumFormatTest.java
/** A number to format */
public static final double intlNumber = 1024.25;
/** Another number to format */
public static final double ourNumber = 100.2345678;
NumberFormat defForm = NumberFormat.getInstance( );
NumberFormat ourForm = new DecimalFormat("##0.##");
// toPattern( ) shows the combination of #0., etc
// that this particular local uses to format with
System.out.println("defForm's pattern is " +
((DecimalFormat)defForm).toPattern( ));
System.out.println(intlNumber + " formats as " +
defForm.format(intlNumber));
System.out.println(ourNumber + " formats as " +
ourForm.format(ourNumber));
System.out.println(ourNumber + " formats as " +
defForm.format(ourNumber) + " using the default format");

This program prints the given pattern and then formats the same number using several formats:

$ java NumFormatTest
defForm's pattern is #,##0.###
1024.25 formats as 1,024.25
100.2345678 formats as 100.23
100.2345678 formats as 100.235 using the default format
$

Java Aligning Strings

Java Aligning Strings

Problem

You want to align strings to the left, right, or center.

Solution

Do the math yourself, and use substring (Recipe 3.1) and a StringBuilder (Recipe 3.3). Or, just use my StringAlign class, which is based on the java.text.Format class.

Explained

Centering and aligning text comes up surprisingly often. Suppose you want to print a simple report with centered page numbers. There doesn’t seem to be anything in the standard API that will do the job fully for you. But I have written a class called StringAlign that will. Here’s how you might use it:


/* Align a page number on a 70-character line. */
public class StringAlignSimple {
 public static void main(String[] args) {
 // Construct a "formatter" to center strings.
 StringAlign formatter = new StringAlign(70, StringAlign.JUST_CENTER);
 // Try it out, for page "i"
 System.out.println(formatter.format("- i -"));
 // Try it out, for page 4. Since this formatter is
 // optimized for Strings, not specifically for page numbers,
 // we have to convert the number to a String
 System.out.println(formatter.format(Integer.toString(4)));
 }
}

If we compile and run this class, it prints the two demonstration line numbers centered, as shown:

> jikes +E -d . StringAlignSimple.java
> java StringAlignSimple
 - i -
 4
>

The code for the StringAlign class. Note that this class extends a class called Format. In the package java.text, there is a series of Format classes that all have at least one method called format( ). It is thus in a family with numerous other formatters, such as DateFormat, NumberFormat, and others, that we’ll meet in upcoming chapters.

StringAlign.java
/** Bare-minimum String formatter (string aligner). */
public class StringAlign extends Format {
 /* Constant for left justification. */
 public static final int JUST_LEFT = 'l';
 /* Constant for centering. */
 public static final int JUST_CENTRE = 'c';
 /* Centering Constant, for those who spell "centre" the American way. */
 public static final int JUST_CENTER = JUST_CENTRE;
 /** Constant for right-justified Strings. */
 public static final int JUST_RIGHT = 'r';
 /** Current justification */
 private int just;
 /** Current max length */
 private int maxChars;
 /** Construct a StringAlign formatter; length and alignment are
 * passed to the Constructor instead of each format( ) call as the
 * expected common use is in repetitive formatting e.g., page numbers.
 * @param nChars - the length of the output
 * @param just - one of JUST_LEFT, JUST_CENTRE or JUST_RIGHT
 */
 public StringAlign(int maxChars, int just) {
 switch(just) {
 case JUST_LEFT:
 case JUST_CENTRE:
 case JUST_RIGHT:
 this.just = just;
 break;
 default:
 throw new IllegalArgumentException("invalid justification arg.");
 }
 if (maxChars < 0) {
 throw new IllegalArgumentException("maxChars must be positive.");
 }
 this.maxChars = maxChars;
 }
 /** Format a String.
 * @param input _ the string to be aligned
 * @parm where - the StringBuffer to append it to.
 * @param ignore - a FieldPosition (may be null, not used but
 * specified by the general contract of Format).
 */
public StringBuffer format(
 Object obj, StringBuffer where, FieldPosition ignore) {
 String s = (String)obj;
 String wanted = s.substring(0, Math.min(s.length( ), maxChars));
 // Get the spaces in the right place.
 switch (just) {
 case JUST_RIGHT:
 pad(where, maxChars - wanted.length( ));
 where.append(wanted);
 break;
 case JUST_CENTRE:
 int startPos = where.length( );
 pad(where, (maxChars - wanted.length( ))/2);
 where.append(wanted);
 pad(where, (maxChars - wanted.length( ))/2);
 // Adjust for "rounding error"
 pad(where, maxChars - (where.length( ) - startPos));
 break;
 case JUST_LEFT:
 where.append(wanted);
 pad(where, maxChars - wanted.length( ));
 break;
 }
 return where;
 }
 protected final void pad(StringBuffer to, int howMany) {
 for (int i=0; i<howMany; i++)
 to.append(' ');
 }
 /** Convenience Routine */
 String format(String s) {
 return format(s, new StringBuffer( ), null).toString( );
 }
 /** ParseObject is required, but not useful here. */
 public Object parseObject (String source, ParsePosition pos) {
 return source;
 }
}