Formatting Data

When preparing output for the viewer, we are likely to want to format it. For example, if we had calculated a mark for a module of study based on two pieces of work, then we could end up with a double with a large number of decimal places. Consider the following code:

double assignmentWeighting = 0.63;
int assigmentGrade = 65;
double examWeighting = 0.37;
int examGrade = 55;
double assignmentValue = assignmentWeighting * assigmentGrade;
double examValue = examWeighting * examGrade;
double moduleTotal = assignmentValue + examValue;
System.out.println("Your module grade is " + moduleTotal);
Because of the way doubles work, the output would be as follows: Your module grade is 61.300000000000004

It would be more useful to provide the value to just one decimal place, and Java provides a number of ways for us to do that.

DecimalFormat

The DecimalFormal class provides a simple way to determine the format that we wish to display a double value in. We simply create a new DecimalFormal object, passing the format as a String into the constructor. The format String is specified using a number of specific characters, however the two most important ones are as follows:

CharacterDisplays
#A number - displayed optionally (i.e. leading and trailing zeros would not be shown)
0A number - displayed (i.e. leading and trailing zeros will be shown (and added if they do not exist)
Once we have an instance of the formatter, we can call it's format method, pass in the double value and it will return a String.

In the above example, if we wanted to display any characters that appear before the decimal point, and only one after it, we would write the code below:

//earlier code omitted for brevity
double moduleTotal = assignmentValue + examValue;
DecimalFormat decimalFormat = new DecimalFormat("#.0");
String moduleTotalString = decimalFormat.format(moduleTotal);
System.out.println("Your module grade is " + moduleTotalString);
//Above line prints "Your module grade is 61.3"

Bear in mind however, that if the person managed to score a value below 1, the their score would be printed as follows: Your module grade is .3. It would therefore be preferable to ensure that at least one digit is printed before the decimal point, so instead we would create the formatter as shown here:

DecimalFormat decimalFormat = new DecimalFormat("0.0");
This means all the digits before the decimal point would appear, and exactly one after it.

Rounding

One key thing to remember is that rounding will occur to the number of specified decimal points, so if the raw value is 9.9999 and the formatter specifies one optional number after the decimal point, the string will simply be "10".

Task

Create formatter such that at least two digits appear before the decimal point, and at least two, but optionally 4 digits appear after the decimal point. For reference, the raw values in the left column in the table below should appear as they do in the right hand column:

Raw ValueFormatted value
0.1234500.1235
123.100003123.10
40.70020040.7002
321.12999321.13

Further task

The formatter allows for a different format for negative numbers. Apply a format such that values are printed in the standard UK currency format (e.g. always 2 decimal places & and £ symbol prefix), but for negative numbers display the values in brackets e.g. (£12.34) instead of £-12.94. Test the formatting works as expected with both postive and negative numbers, with varying numbers of decimal places in the initial double value.

String.format method

The String class also has a method for formatting values. This can inject values into a String literal with particular formatting.

Task

Using the String.format() method, and given these existing lines of code:

String name = "Dave";
int age = 43;
double BMI = 22.566666666
Determine how to, in just one further line of code, and without using concatenation (i.e. the + operator) create a String that, if printed, would read as follows: Dave is 43 and has a BMI of 22.6

Research task - java.util.Formatter

Yet another class exists for formatting data: java.util.Formatter. Carry out research to determine what functionality this class offers and create versions the code from the tasks above which make use of it.