slanted W3C logo

Day 09 — Output Formatting

In today's lecture we look at formatting the output of integer and real numbers using the printf method in the java.io.PrintStream class.

Drawing Circles 1

You can think of your computer display as being a regular grid of points of light (pixels) with each pixel having a coordinate [x y] where x and y are both integers.

Suppose you want to draw a circle on the display. An easy (but not very good) way to draw a circle is to use the parametric equation of a circle:

x = R * cos(θ)
y = R * sin(θ)

where θ is the angle measured counter-clockwise from the positive x-axis and R is the radius of the circle.

Write a Java program named Circle1 that computes the coordinates of a point on a circle given user input values of the radius and angle; the values for the radius and angle may be real numbers. An example run of the program is shown below:

Enter the circle radius ... 10
Enter the angle in degrees ... 45.0
...
The coordinates are [7.0710678118654755 7.071067811865475]

The numbers in red in the example above were entered by the user (not output by the program).

Step 1: Modify the Template Program

Here we are using the labtest template program.

/* Your Name Here
 * Your CSE Login Here
*/

import java.io.PrintStream;
import java.util.Scanner;

public class Circle1
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       Scanner input = new Scanner(System.in);

   }
}

Notice that the class name is Circle1 as specified by the problem.

Step 2: Output a Prompt to the User

/* Your Name Here
 * Your CSE Login Here
*/

import java.io.PrintStream;
import java.util.Scanner;

public class Circle1
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       Scanner input = new Scanner(System.in);

       output.print("Enter the circle radius ... ");
   }
}

Notice that we use output.print because we do not want the newline to appear after the prompt.

Step 3: Get the User Input

/* Your Name Here
 * Your CSE Login Here
*/

import java.io.PrintStream;
import java.util.Scanner;

public class Circle1
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       Scanner input = new Scanner(System.in);

       output.print("Enter the circle radius ... ");
       double radius = input.nextDouble();
   }
}

Notice that we use input.nextDouble because the problem says that the value for the radius can be a real number.

Step 4: Ask for and get the Angle

/* Your Name Here
 * Your CSE Login Here
*/

import java.io.PrintStream;
import java.util.Scanner;

public class Circle1
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       Scanner input = new Scanner(System.in);

       output.print("Enter the circle radius ... ");
       double radius = input.nextDouble();
       output.print("Enter the angle in degrees ... ");
       double deg = input.nextDouble();
   }
}

Step 5: Compute the Coordinates

If you look up the API for Math.cos and Math.sin you will see that the methods expect the angle to be in radians; however, we have the angle in degrees. Fortunately, the method Math.toRadians can compute the number of radians given an angle in degrees.

/* Your Name Here
 * Your CSE Login Here
*/

import java.io.PrintStream;
import java.util.Scanner;

public class Circle1
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       Scanner input = new Scanner(System.in);

       output.print("Enter the circle radius ... ");
       double radius = input.nextDouble();
       output.print("Enter the angle in degrees ... ");
       double deg = input.nextDouble();

       double rad = Math.toRadians(deg);
       double x = radius * Math.cos(rad);
       double y = radius * Math.sin(rad);
   }
}

Step 6: Output the Result

/* Your Name Here
 * Your CSE Login Here
*/

import java.io.PrintStream;
import java.util.Scanner;

public class Circle1
{
   public static void main(String[] args)
   {
       PrintStream output = System.out;
       Scanner input = new Scanner(System.in);

       output.print("Enter the circle radius ... ");
       double radius = input.nextDouble();
       output.print("Enter the angle in degrees ... ");
       double deg = input.nextDouble();

       double rad = Math.toRadians(deg);
       double x = radius * Math.cos(rad);
       double y = radius * Math.sin(rad);

       output.println("...");
       output.print("The coordinates are [");
       output.print(x);
       output.print(" ");
       output.print(y);
       output.println("]");
   }
}

Formatted Output

The PrintStream class defines a method that lets the client specify the format of the output.

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class IntPrintfExample1
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter an int value : ");
      int anInt = input.nextInt();

      out.println();
      out.println("The number");
      out.printf("%d", anInt);
      out.println();
   }
}

In the example above, "%d" is called the formatting string and anInt is the number to be formatted.

"%d" means format as an integer number.

Formatted Output

The formatting string can also contain ordinary text for output.

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class IntPrintfExample2
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter an int value : ");
      int anInt = input.nextInt();

      out.println();
      out.printf("The number %d", anInt);
      out.println();
   }
}

Formatted Output

A newline can be output using %n

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class IntPrintfExample3
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter an int value : ");
      int anInt = input.nextInt();

      out.printf("%nThe number %d%n", anInt);
   }
}

Formatted Output

You can specify the minimum width of the output.

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class IntPrintfExample4
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter an int value : ");
      int anInt = input.nextInt();

      out.printf("%nThe number using at least 10 spaces %10d%n", anInt);
   }
}

Formatted Output

You can force the output of the sign of the number.

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class IntPrintfExample5
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter an int value : ");
      int anInt = input.nextInt();

      out.printf("%nThe number with its sign %+d%n", anInt);
   }
}

Formatted Output

You can force the output of the grouping separator.

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class IntPrintfExample6
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter an int value : ");
      int anInt = input.nextInt();

      out.printf("%nThe number with its grouping separator %,d%n", anInt);
   }
}

Formatted Output

You can choose which arguments to format.

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class IntPrintfExample7
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter three int values : ");
      int first = input.nextInt();
      int second = input.nextInt();
      int third = input.nextInt();

      out.printf("%nThe numbers in reverse order %3$d %2$d %1$d%n", first, second, third);
   }
}

Formatted Output

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class IntPrintfExamples
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter an int value : ");
      int anInt = input.nextInt();

      out.println("\n\nThe number");
      out.printf("%d", anInt);

      out.println("\n\nThe number with two newlines after");
      out.printf("%d%n%n", anInt);

      out.println("The number using at least 10 spaces");
      out.printf("%10d%n%n", anInt);

      out.println("The number using at least 15 spaces");
      out.printf("%15d%n%n", anInt);

      out.println("The number with its sign");
      out.printf("%+d%n%n", anInt);

      out.println("The number with grouping separator");
      out.printf("%,d%n%n", anInt);

      out.println("The number with its sign and grouping separator using at least 10 spaces");
      out.printf("%+,10d%n%n", anInt);

      out.println("The number three times separated with a space");
      out.printf("%1$d %1$d %1$d%n%n", anInt);

      out.println("The number three times with different formatting");
      out.printf("%1$+d %1$,10d %1$+,10d%n%n", anInt);
   }
}

Formatted Output

Formatted output of real numbers is similar except that you use an f instead of d and you can also specify the precision (number of digits after the decimal place).

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class DoublePrintfExample1
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter a double value : ");
      double aReal = input.nextDouble();

      out.printf("%nThe number to 2 decimal places %.2f%n", aReal);
   }
}

Formatted Output

Another example formatting a real value as dollars and cents.

import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class DoublePrintfExample2
{
   public static void main(String[] args)
   {
      InputStream in = System.in;
      PrintStream out = System.out;

      Scanner input = new Scanner(in);

      out.print("Enter a double value : ");
      double aReal = input.nextDouble();

      out.printf("%nThe number as a monetary amount $%,.2f%n", aReal);
   }
}

Drawing Circles 2

Write a Java program named Circle2 that behaves like the first one, except that the output is different. The coordinates should be output to 3 decimal places, and the coordinates rounded to the nearest integer should also be output.

Try to use only two printf invocations to perform all of the output .

Enter the circle radius ... 10
Enter the angle in degrees ... 45.0
...
The coordinates are [7.071 7.071]
The rounded coordinates are [7 7]

Consider using Math.round to compute the coordinates rounded to the nearest integer.

Bonus: can you duplicate the functionality of Math.round for positive values using only some arithmetic and a cast?

Self Check

  1. Key concepts at the end of Chapter 3.
  2. Review questions at the end of Chapter 3.
  3. Problems at end of the slides.

To Do For Next Lecture

  1. Read Sections 4.1 and 4.2 in the textbook.

Drawing Circles 3

Write a Java program named Circle3 that behaves like the first one, this time without using cos or sin from java.lang.Math.

Hint: you can use the following approximations:

sin(x) = x - (x3 / 6) + (x5 / 120) - (x7 / 5040)
cos(x) = 1 - (x2 / 2) + (x4 / 24) - (x6 / 720)

An example run of the program is shown below:

Enter the circle radius ...
10
Enter the angle in degrees ...
45.0
...
The coordinates are [7.071032148228457 7.071064695751781]

The numbers in red in the example above were entered by the user (not output by the program).

What happens to the computed coordinates as the value entered by the user for the angle increases? Why do the approximations for sin and cos deteriorate for large angles? How might you fix the problem?

Taxes and Tips

At a restaurant in Ontario, you are charged 5% GST and 8% PST on all food items. Some people tip the wait staff on the before tax amount and some people tip on the after tax amount.

Write a Java program that asks the user for the total bill before taxes and the percentage that they wish to tip; the program should output the amount of the tip based on both the before and after tax amounts. The output should be formatted to two decimal places (i.e. like a monetary amount).

Here is an example output:

Enter the total bill amount before taxes ... 100.25
Enter the tip rate ... 15

Tip on before tax amount ... 15.04
Tip on after tax amount ... 28.07