TYPE CONVERSIONS INTRODUCTION TO PROGRAMMING IN JAVA: TYPE CONVERSIONS NOTE: This set of www pages is not the set of www pages for the curent version of COMP101. The pages are from a previous version that, at the request of students, I have kept on line. CONTENTS 1. Introduction to type conversion 1.1. Automatic conversion 1.2. Explicit conversion 1.3. The distinction between casting and "rounding" 2. Example problem - 2-D geographic distance 2.1. Requirements 2.2. Analysis 2.3. Design 2.4. Implementation 2.5. Testing 3. Test harness for 2-D geographic distance application program" The example problem includes an illustration of the passing of instances as arguments. It also gives an illustration of the use of the abs method from the Math class, using a float data type, and how to "return" an object from a method (we looked at returning standard data items in the previous lecture. 1. INTRODUCTION TO TYPE CONVERSION It is sometimes necessary to convert a data item of one type to another type. For example when it is necessary to perform some arithmetic using data items of different types (so called mixed mode arithmetic). Under certain circumstances Type conversion can be carried out automatically, in other cases it must be "forced" manually (explicitly). 1.1 Automatic Conversion In Java type conversions are performed automatically when the type of the expression on the right hand side of an assignment operation can be safely promoted to the type of the variable on the left hand side of the assignment. Thus we can safely assign: byte -> short -> int -> long -> float -> double The -> symbol used here should be interpreted as "to a". For example:
// 64 bit long integer
long myLongInteger;
// 32 bit standard integer
int myInteger;
myLongInteger = myInteger;
The extra storage associated with the long integer, in the above example, will simply be padded with extra zeros. 1.2 Explicit Conversion (Casting) The above will not work the other way round. For example we cannot automatically convert a long to an int because the first requires more storage than the second and consequently information may be lost. To force such a conversion we must carry out an explicit conversion (assuming of course that the long integer will fit into a standard integer). This is done using a process known as a type cast:
myInteger = (int) myLongInteger
This tells the compiler that the type of myLongInteger must be temporarily changed to a int when the given assignment statement is processed. Thus, the cast only lasts for the duration of the assignment. Java type casts have the following form:
(T) N
where T is the name of a numeric type and N is a data item of another numeric type. The result is of type T. 1.3 Distinction Between Casting and Rounding Given a data item of type double or a float we can change the type of this item so that it becomes a data item of type long or int using a cast operation as described above. What happens in this case is that the exponent part of the real number is simply omitted. For example 99.9999 will become 99. In cases such as this it might be more desirable to say that the integer equivalent of 99.9999 is 100 (i.e. round up). We cannot achieve this using a cast, however the Java Math class contains methods to achieve this, namely the methods rint and round. The first rounds a double up or down to its nearest integer equivalent (without converting the type). The second has two versions, one to round and convert a float to an int, and one to round and convert a double to a long. Consider the Java code given in Table 1. The code allows a user to input a double which is then output; first as an integer using a cast, then as an integer using the round method, and then as double rounded to the nearest integer.
// ROUNDING EXAMPLE APPLICATION CLASS
// Frans Coenen
// Tuesday 13 April 1999
// The University of Liverpool, UK
// Revised Rgursday 22 June 2005
import java.util.*;
class RoundingEx {
// ------------------- FIELDS ------------------------
// Create BufferedReader class instance
private static Scanner input = new Scanner(System.in);
// ------------------ METHODS -----------------------
/* Main method */
public static void main(String[] args) {
// Input
System.out.print("Input a double precision number = ");
double inputDouble = input.nextDouble();
// Output
System.out.println("Input converted to an int using a " +
"cast = " + (int) inputDouble);
System.out.println("Input converted to an int using 'round' " +
"method = " + Math.round(inputDouble));
System.out.println("Input converted to an \"int\" using 'rint' " +
"method = " + Math.rint(inputDouble));
}
}
Table 1: Rounding example program Some example output is given in Table 2. Note that a value of 1.5 is rounded upwards.
$ java RoundingEx
Input a double precision number = 1.2
Input converted to an int using a cast = 1
Input converted to an int using 'round' method = 1
Input converted to an "int" using 'rint' method = 1.0
$ java RoundingEx
Input a double precision number = 1.8
Input converted to an int using a cast = 1
Input converted to an int using 'round' method = 2
Input converted to an "int" using 'rint' method = 2.0
$ java RoundingEx
Input a double precision number = 1.5
Input converted to an int using a cast = 1
Input converted to an int using 'round' method = 2
Input converted to an "int" using 'rint' method = 2.0
Table 2: Example output produced by code presented in Table 1 Note: In the following example problem we are going to use a cast to convert a double to a float. The example will also illustrate how we can pass instances as arguments (to date we have only considered the passing of primitive data items as opposed to more complex higher level data items. 2. EXAMPLE PROBLEM 2-D GEOGRAPHIC DISTANCE 2.1 Requirements Design and implement a Java program that determines the geographical distance between two points located on a geographic plane. The points are referenced using the standard {X,Y} Cartesian coordinate system founded on a 0 origin (see Figure 1). The procurer requires that input should be in the form of floats (and not standard double precision real numbers). Figure 1: 2-D space geometry 2.2 Analysis A class diagram for the proposed solution is presented in Figure 2. This involves using the Triangle class methods to calculate the distance. Thus we need a class Point_2D for the two points which contains a method to calculate distance which in turn calls the method calculateHypotenuse in the Triangle class to do the actual calculation. Fig 2: 2-D geographic distance class diagram 2.3 Design From Figure 2 the design requires two new classes, Point_2D and Geo2DdistApp. 2.3.1 Point_2D Class Field Summary private float xCoord An instance field to store X-coordinate of an instance of the class Point_2D. private float y_coord An instance field to store Y-coordinate of an instance of the class Point_2D. Constructor Summary Point_2D(float newX, float newY) Constructs an instance of the class Point_2D given given a pair of X-Y values. Method Summary public float geoDist_2D(Point_2D pointTwo) Instance method to calculate the distance between two points. This is achieved by first calculating the differences in x and y and then using these differences to create an instance of the Triangle class. The calculateHypotenuse method contained in the Triangle class is then used to determine the hypotenuse of the triangle which will be equivalent to the distance between the two points. The calculateHypotenuse method will pass the result (distance) back as a data item of type double, we require a float, therefore we must carry out an appropriate "cast". The result is then returned to the calling method. Nassi-Shneiderman charts for the above two methods are presented in Figure 3. Fig 3: Nassi-Shneiderman charts for Point_2D class methods 2.3.2 Geo2DdistApp Class Field Summary private static Scanner input A class instance field to facilitate input from the input stream. Method Summary public static void main(String[] args) Main method. Creates two instances of the class Point_2D using the create2Dpoint method. Then causes the distance between the two points to be calculated using the geoDist_2D method described above, and outputs the result. private static Point_2D create2Dpoint(int pointNumber) Method to create an instances of the class Point_2D given specific x and y coordinates input by the user. The formal parameter is used for display purposes only. A Nassi-Shneiderman for the above is presented in Figure 4. Fig 4: Nassi-Shneiderman charts for Geo2DdistApp class method 2.4. Implementation 2.4.1 Point_2D class
// (2-D) COORDINATE
// Frans Coenen
// Wednesday 3 March 1999
// University of Liverpool
class Point_2D {
// ---------------------- FIELDS ---------------------
private float x_coord;
private float y_coord;
// ------------------ CONSTRUCTORS -------------------
/* Constructor */
public Point_2D(float newX, float newY) {
x_coord = newX;
y_coord = newY;
}
// --------------------- METHODS ---------------------
/* Method to Calculate 2-D geographic distance. (Method
uses method in Triangle class to do this). */
public float geoDist_2D(Point_2D pointTwo) {
float diffInX, diffInY, distance;
// Calculate differences
diffInX = Math.abs(pointTwo.x_coord - x_coord);
diffInY = Math.abs(pointTwo.y_coord - y_coord);
// Resolve "triangle" using Triangle class methods
Triangle newTriangle = new Triangle(diffInX,diffInY);
newTriangle.calculateHypotenuse();
distance = (float) newTriangle.getHypotenuse();
// Return result
return(distance);
}
}
Table 3: Point_2D class implementation Note: although diffInX and diffInY are of type float and the Triangle constructor requires data items (arguments) of type double, the floats will be "coerced" into doubles without requiring an explicit cast. The value returned however (a double) must be cast to be of type float. 2.4.2 Geo2DdistApp class
// GEOGRAPHIC 2-D DISTANCE APPLICATION
// Frans Coenen
// Wednesday 3 March 1999
// Revised: Thursday 12 May 2005
// University of Liverpool
import java.util.*;
class Geo2DdistApp {
// ------------------- FIELDS ------------------------
// Create BufferedReader class instance
private static Scanner input = new Scanner(System.in);
// ------------------ METHODS ------------------------
/** Main method */
public static void main(String argv[]) {
// Create points 1 and 2
Point_2D point1 = create2Dpoint(1);
Point_2D point2 = create2Dpoint(2);
// Calculate distance and output
float geoDistance = point1.geoDist_2D(point2);
System.out.println("Geographic distance = " + geoDistance);
}
/* CREATE 2D POINT: Method to input x and y for point 1, echo to screen
and then create an instance of the class Point_2D */
private static Point_2D create2Dpoint(int pointNumber) {
// Invite input
System.out.println("Input x coord for point " + pointNumber +
" (floats)");
float x_coord = input.nextFloat();
System.out.println("Input y coord for point " + pointNumber +
" (floats)");
float y_coord = input.nextFloat();
System.out.println("Point " + pointNumber + ": x = " + x_coord +
" y = " + y_coord);
// Create instance of class Point_2D
Point_2D newPoint = new Point_2D(x_coord,y_coord);
// Return
return(newPoint);
}
}
Table 4: Geographic 2-D distance application implementation 2.5. Testing Arithmetic testing: We have four input values which can be negative, zero or positive. Thus there are a total of 81 (3x3x3x3) test cases to consider (see table below). TEST CASE EXPECT. RESULT X1 Y1 X2 Y2 distance 4.0 4.0 3.0 3.0 1.4142135 4.0 4.0 3.0 0.0 4.1231055 4.0 4.0 3.0 -3.0 7.071068 4.0 4.0 0.0 3.0 4.1231055 4.0 4.0 0.0 0.0 5.656854 4.0 4.0 0.0 -3.0 8.062258 4.0 4.0 -3.0 3.0 7.071068 4.0 4.0 -3.0 0.0 8.062258 4.0 4.0 -3.0 -3.0 9.899495 4.0 0.0 3.0 3.0 3.1622777 4.0 0.0 3.0 0.0 1.0 4.0 0.0 3.0 -3.0 3.1622777 4.0 0.0 0.0 3.0 5.0 4.0 0.0 0.0 0.0 4.0 4.0 0.0 0.0 -3.0 5.0 4.0 0.0 -3.0 3.0 7.615773 4.0 0.0 -3.0 0.0 7.0 4.0 0.0 -3.0 -3.0 7.615773 4.0 -4.0 3.0 3.0 7.071068 4.0 -4.0 3.0 0.0 4.1231055 4.0 -4.0 3.0 -3.0 1.4142135 4.0 -4.0 0.0 3.0 8.062258 4.0 -4.0 0.0 0.0 5.656854 4.0 -4.0 0.0 -3.0 4.1231055 4.0 -4.0 -3.0 3.0 9.899495 4.0 -4.0 -3.0 0.0 8.062258 4.0 -4.0 -3.0 -3.0 7.071068 TEST CASE EXPECT. RESULT X1 Y1 X2 Y2 distance 0.0 4.0 3.0 3.0 3.1622777 0.0 4.0 3.0 0.0 5.0 0.0 4.0 3.0 -3.0 7.615773 0.0 4.0 0.0 3.0 1.0 0.0 4.0 0.0 0.0 4.0 0.0 4.0 0.0 -3.0 7.0 0.0 4.0 -3.0 3.0 3.1622777 0.0 4.0 -3.0 0.0 5.0 0.0 4.0 -3.0 -3.0 7.615773 0.0 0.0 3.0 3.0 4.2426405 0.0 0.0 3.0 0.0 3.0 0.0 0.0 3.0 -3.0 4.2426405 0.0 0.0 0.0 3.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -3.0 3.0 0.0 0.0 -3.0 3.0 4.2426405 0.0 0.0 -3.0 0.0 3.0 0.0 0.0 -3.0 -3.0 4.2426405 0.0 -4.0 3.0 3.0 7.615773 0.0 -4.0 3.0 0.0 5.0 0.0 -4.0 3.0 -3.0 3.1622777 0.0 -4.0 0.0 3.0 7.0 0.0 -4.0 0.0 0.0 4.0 0.0 -4.0 0.0 -3.0 1.0 0.0 -4.0 -3.0 3.0 7.615773 0.0 -4.0 -3.0 0.0 5.0 0.0 -4.0 -3.0 -3.0 3.1622777 TEST CASE EXPECT. RESULT X1 Y1 X2 Y2 distance -4.0 4.0 3.0 3.0 7.071068 -4.0 4.0 3.0 0.0 8.062258 -4.0 4.0 3.0 -3.0 9.899495 -4.0 4.0 0.0 3.0 4.1231055 -4.0 4.0 0.0 0.0 5.656854 -4.0 4.0 0.0 -3.0 8.062258 -4.0 4.0 -3.0 3.0 1.4142135 -4.0 4.0 -3.0 0.0 4.1231055 -4.0 4.0 -3.0 -3.0 7.071068 -4.0 0.0 3.0 3.0 7.615773 -4.0 0.0 3.0 0.0 7.0 -4.0 0.0 3.0 -3.0 7.615773 -4.0 0.0 0.0 3.0 5.0 -4.0 0.0 0.0 0.0 4.0 -4.0 0.0 0.0 -3.0 5.0 -4.0 0.0 -3.0 3.0 3.1622777 -4.0 0.0 -3.0 0.0 1.0 -4.0 0.0 -3.0 -3.0 3.1622777 -4.0 -4.0 3.0 3.0 9.899495 -4.0 -4.0 3.0 0.0 8.062258 -4.0 -4.0 3.0 -3.0 7.071068 -4.0 -4.0 0.0 3.0 8.062258 -4.0 -4.0 0.0 0.0 5.656854 -4.0 -4.0 0.0 -3.0 4.1231055 -4.0 -4.0 -3.0 3.0 7.071068 -4.0 -4.0 -3.0 0.0 4.1231055 -4.0 -4.0 -3.0 -3.0 1.4142135 Data validation: Finally we should carry out some tests using deliberately spurious data. 3. TEST HARNESS FOR 2-D GEOGRAPHIC DISTANCE APPLICATION A test harness to carry out the required testing is presented in Table 5. Note: to indicate to Java that the numeric literals are floats we need to include an f, e.g. 4.0f.
// GEOGRAPHIC 2-D DISTANCE TEST
// Frans Coenen
// Wednesday 3 March 1999
// University of Liverpool
import java.io.*;
class Geo2DdistTest {
// ---------------- FIELDS -------------------
// ---------------- METHODS ------------------
/* Main method, input X coordinate for point 1 */
public static void main(String argv[]) throws IOException {
inputYcoordForPoint1(4.0f);
inputYcoordForPoint1(0.0f);
inputYcoordForPoint1(-4.0f);
}
// Input Y coordinate for point 1
public static void inputYcoordForPoint1(float x_coord1) {
inputXcoordForPoint2(x_coord1,4.0f);
inputXcoordForPoint2(x_coord1,0.0f);
inputXcoordForPoint2(x_coord1,-4.0f);
}
// Input X coordinate for point 2
public static void inputXcoordForPoinr2(float x_coord1, float y_coord1) {
inputYcoordForPoint2(x_coord1,y_coord1,3.0f);
inputYcoordForPoint2(x_coord1,y_coord1,0.0f);
inputYcoordForPoint2(x_coord1,y_coord1,-3.0f);
}
// Input Y coordinate for point 2
public static void inputYcoordForPoinr2(float x_coord1, float y_coord1,
float x_coord2) {
claculateDistance(x_coord1,y_coord1,x_coord2,3.0f);
claculateDistance(x_coord1,y_coord1,x_coord2,0.0f);
claculateDistance(x_coord1,y_coord1,x_coord2,
-3.0f);
}
// Calculate distance
public static void claculateDistance(float x_coord1, float y_coord1,
float x_coord2, float y_coord2) {
float geoDistance;
// Echo x and y for point 1 to screen and then create the instance
// point1
System.out.print("Point1: x = " + x_coord1 + " y = " + y_coord1);
Point_2D point1 = new Point_2D(x_coord1,y_coord1);
// Echo x and y for point 2 to screen and then create the instance
// point2
System.out.print(", Point2: x = " + x_coord2 + " y = " + y_coord2);
Point_2D point2 = new Point_2D(x_coord2,y_coord2);
// Calculate distance and output
geoDistance = point1.geoDist_2D(point2);
System.out.println(", Distance" + geoDistance);
}
}
Table 5: Test harness implementation for geographic 2-D distance application Created and maintained by Frans Coenen. Last updated 10 February 2015