Formatting numbers in Java

Download Report

Transcript Formatting numbers in Java

Formatting
Putting Values into a
Suitable Form for
Display
Copyright © 2006 Curt Hill
The Problem
• Java uses types int and double to
represent numeric values
• These have a binary internal
representation
• People want to see a character
representation in a report or in a
window
• There are many such
representations
Copyright © 2006 Curt Hill
What we want
• Although the basic digits are the
same we may want to see other
information
• Commas separating groups of digits
• Leading/trailing zero suppression
• Currency symbols such as $
• Handling of the sign other than a
leading + / – Such as CR or DB
• We call this editing
Copyright © 2006 Curt Hill
If that is not bad enough
• Java is an international language
• The problem is complicated by
different locales
• Do you want:
– 341,450.78 – Common in America
– 341.450,78 – Common in Europe
– 341 450,78 – Also used in Europe
• Just as most Operating Systems
keep track of this Java does as well
Copyright © 2006 Curt Hill
The Problem Revisited
• The Java compiler is notoriously
poor at guessing the intent of the
programmer
• So the default formatting is usually
insufficient
• We will need to specify more
information to get what we want
• This will involve new classes and
new methods
Copyright © 2006 Curt Hill
NumberFormat
• We will use a NumberFormat object
to format numbers into strings
• It has several methods that will be of
interest
• The format method will either take a
long int or a double
– An int will automatically cast into a long
as also a float into a double
• This method will return a string
which is the formatted number
Copyright © 2006 Curt Hill
NumberFormat
• NumberFormat is an abstract base
class
• It is the ancestor of several classes
that will be important
• The actual class will determine the
formatting
• As an abstract base class it cannot
be instantiated
• What does that mean?
Copyright © 2006 Curt Hill
Abstract Base Classes
• NumberFormat is an abstract base
class
• Does that mean we cannot:
NumberFormat nf;
• No
• It means that we cannot:
nf = new NumberFormat(…);
• The variable nf may hold any
descendent of NumberFormat
Copyright © 2006 Curt Hill
NumberFormat Descendents
• The currency classes are simple but
not too simple
• DecimalFormat is the most general
and complicated
• Before dealing with the currency
descendents and instantiating an
abstract base class we need to
consider a Locale object
Copyright © 2006 Curt Hill
Locale
• A Locale is an object that represents
a region
• This captures both geography and
language
• Used to modify how things are
displayed
• Specifically currency symbols and
format of numbers
• Create a Locale object if you do not
want your own
Copyright © 2006 Curt Hill
Locale Constructors
• The constructor may specify a
language, nation or system
• Locale loc = new Locale(“en”);
– English, default country
• Locale loc =
new Locale(“en”,”GB”);
– English of Great Britain
• Locale loc =
new Locale(“en”,”US”,”MAC”);
– English, USA for a MacIntosh system
Copyright © 2006 Curt Hill
Alternative
• Often it is easier to use static
Locales
• Locale loc = Locale.UK;
– instead of previous
• Locale loc = Locale.CANADA;
– English for Canadians
• Locale loc =
Locale.CANADA_FRENCH;
– French for Canadians
Copyright © 2006 Curt Hill
Abstract Base Classes Again
• Suppose
NumberFormat nf;
• We cannot use:
nf = new NumberFormat(…);
• How then do we?
• We use the NumberFormat method
getCurrencyInstance to make a
descendent of NumberFormat that is
instantiable
Copyright © 2006 Curt Hill
Currencies
• There are several descendents of
NumberFormat that represent the
currencies of various locales
• The NumberFormat static method
getCurrencyInstance is used to
obtain
• If no parameter then get the Locale
for this machine:
nf = NumberFormat.
getCurrencyInstance();
Copyright © 2006 Curt Hill
Formatting for Currency
• We now know the process:
– Declare a NumberFormat object
– Initialize with getCurrencyInstance
– Use format method to create the string
• Now look at the example code:
Copyright © 2006 Curt Hill
Example
double d;
… // load d with value
NumberFormat nf;
nf = nf.getCurrencyInstance();
String s = nf.format(d);
… // display s somewhere
The nf before getCurrencyInstance could
have been spelled out as
NumberFormat, since this is a static
method
Copyright © 2006 Curt Hill
getCurrencyInstance
• Has two signatures
• One without parameters
• One with a Locale object as a
parameter
• Use the latter to display currencies
different than the local one
• See example
Copyright © 2006 Curt Hill
Example
double d;
… // load d with value
NumberFormat nf;
Locale loc = Locale.UK;
nf = nf.getCurrencyInstance(loc);
String s = nf.format(d);
… // display s somewhere
Now a pound symbol will be displayed instead
of a dollar sign
Copyright © 2006 Curt Hill
Not yet enough
• It is one thing to put us in correct
locale, it is another thing to use the
right currency symbol
• In London they are just as likely to
accept a Euro or Dollar as a Pound
• How is formatting for Euros in
London different than formatting
Euros in France?
• The formatting is based on Locale,
but other currency symbols can be
used
Copyright © 2006 Curt Hill
Currency
• A class that describes what symbol
to use in currency formatting
• We will use a static method to
create, somewhat like
NumberFormat
• We can create one with a three
character abbreviation
Currency newCurrency =
Currency.getInstance("EUR");
Copyright © 2006 Curt Hill
Currency continued
• There are several abbreviations that
are usable:
– USD = US Dollar
– HKD = Hong Kong Dollar
– EUR = Euro
• Use setCurrency to establish that in
a NumberFormat object
• See the next example
Copyright © 2006 Curt Hill
Formatting Euros in England
Currency newCurrency =
Currency.getInstance("EUR");
NumberFormat nf;
Locale loc = Locale.UK;
nf =
nf.getCurrencyInstance(loc);
nf.setCurrency(newCurrency);
String s = nf.format(d);
… // display s somewhere
Copyright © 2006 Curt Hill
There is always more
• Formatting a number as currency is
an important task
• There are many other ways to
format a number
• How do we do this?
• Use the DecimalFormat object
• This generalizes most any type of
formatting
Copyright © 2006 Curt Hill
DecimalFormat
•
•
•
•
Descendent of NumberFormat
Will use the format method
Uses a pattern to edit the text
This pattern is similar to many other
numeric editing patterns
– The PIC clause in COBOL
– Numerous others
• The pattern is just a string of
characters
Copyright © 2006 Curt Hill
Pattern Format
• Just a string
• Each character in string is either an
editing character or will appear as-is
• Editing characters have a special
meaning for the formatting
• The semicolon divides the pattern
into two pieces
– First is how to handle if number is
positive
– The second is for negatives
Copyright © 2006 Curt Hill
Pattern Characters
• # means a digit, with leading zero
suppression
• 0 means a digit that always displays
• . Decimal separator
• - Minus sign
• , Grouping separator
• E Separates mantissa and exponent in
scientific notation
• % Multiply by 100 and show as
percentage
• ' Used to quote special characters in a
prefix or suffix
– "'#'#" formats 123 to "#123“
Copyright © 2006 Curt Hill
Suppression
• Only certain values may exist within
the number
– Such as the comma
• These will also be suppressed just
like a digit
• The result string may be shorter
than the pattern
• Any characters may be outside the
number representation string
– They will display as themselves
Copyright © 2006 Curt Hill
Rounding
• When a float or double is cast as an
int truncation occurs
– All digits to right of decimal are lost
• Formatting always rounds
– Not to the nearest integer
– To nearest displayable number
• Thus using “###.###” the number
1.23461 will become 1.235
• This is true of all descendents of
NumberFormat
Copyright © 2006 Curt Hill
Imports
• Several new import statements are
needed for this
• import java.text.NumberFormat;
• import
java.text.DecimalFormat;
• import java.util.Locale;
• import java.util.Currency;
Copyright © 2006 Curt Hill
Conclusion
• There are simple and more
complicated ways to make the
number look the way we would like
• NumberFormat with
getCurrencyInstance is the simplest
way for currency displays
• DecimalFormat is the most general
and should be able to do any display
Copyright © 2006 Curt Hill