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.
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(θ)
where
y = R * sin(θ)
θ
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).
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.
output.print
,
output.println
, or output.printf
input.nextInt
, input.nextLong
,
input.nextFloat
, input.nextDouble
, etc.
/* 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.
/* 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.
/* 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();
}
}
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);
}
}
/* 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("]");
}
}
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.
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(); } }
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); } }
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); } }
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); } }
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); } }
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); } }
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 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); } }
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); } }
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?
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?
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