Today we look at operations with the floating-point types and what happens when types mix in arithmetic expressions.
double
We have already seen the double
type used to represent
real numbers. The range of values that can be represented by the
type is approximately:
Minimum Value | Maximum Value |
-1.7 × 10308 | 1.7 × 10308 |
All of the operators we have seen so far
can be used with double
types.
Operations with double
can overflow. If overflow occurs,
the result is set to a value representing positive infinity (if the value
is positive) or negative infinity (if the value is negative).
The value 0.0 / 0.0
is called NaN
or not a
number. Division by 0.0
with other double
values produces either positive or negative infinity.
public class DoubleClosureExamples { public static void main(String[] args) { // positive overflow double x = 1E200; System.out.println(x * x); // negative overflow System.out.println(-x * x); // NaN double zero = 0.0; System.out.println(zero / zero); // positive overflow (division by 0.0) System.out.println(x / zero); // negative infinity (division by 0.0) System.out.println(-x / zero); } }
Suppose you pay $5.00 for three candy bars costing $1.10 each. How much change should you get back? Write a Java program that solves the problem in three different ways:
(3 * 1.10)
3.30
as the
total cost of the candy bars1.70
.
Use the subtraction operator to calculate the
final result, and you should use double
s for the monetary
values. Compare all three results using Java's equality operator
==
.
The following program
public class MakingChange { public static void main(String[] args) { double change1 = 5.0 - (3 * 1.1); double change2 = 5.0 - 3.3; double change3 = 1.7; System.out.println(change1 == change2); System.out.println(change1 == change3); System.out.println(change2 == change3); } }
outputs:
false false false
Almost every decimal number is represented by an approximate value on a computer (because of the way most computers store decimal numbers).
Do not use double
to repesent monetary amounts;
instead, convert everything to cents and use int
or long
to perform the calculatioins.
float
The float
type is also used to represent
real numbers but it has a smaller range and less precision than
double
. The range of values that can be represented by the
type is approximately:
Minimum Value | Maximum Value |
-3.4 × 1038 | 3.4 × 1038 |
A float
occupies 4 bytes of memory and has about
7 significant digits. All of the operators we have seen so far
can be used with float
types.
A float
literal is a number followed by
an F
or an f
; for example:
-5F
or -5f
3.1415F
or 3.1415f
2.99792E8F
or 2.99792E8f
Most of the time you would prefer double
over
float
unless lack of memory is an issue.
If you mix types in an arithmetic expression the results can be confusing. You need to apply the precedence rules and associativity rules to determine the order in which the operands are evaluated, and then apply the following set of rules:
double
then
the other operand is promoted to type double
float
then
the other operand is promoted to type float
long
then
the other operand is promoted to type long
int
Assume that for each of the following examples shown in the table below we have the declarations:
double xDouble = 10.0; float xFloat = 5.0F; long xLong = 4L; int xInt = 2; short xShort = 1;
Expression | Evaluation |
xFloat + xDouble |
⇒ ((double) xFloat) + xDouble ⇒ 15.0 |
xFloat * xLong |
⇒ xFloat * ((float) xLong) ⇒ 20F |
xInt - xLong |
⇒ ((long) xInt) - xLong ⇒ -2L |
xShort + xShort |
⇒ ((int) xShort) + ((int) xShort) ⇒ 2 |
+xShort |
⇒ +((int) xShort) ⇒ +1 |
-xShort |
⇒ -((int) xShort) ⇒ -1 |
In an assignment statement involving the primitive numeric types, the Java compiler will promote the right-hand side value (perform a widening conversion) but it will not demote the value (perform a narrowing conversion).
If you have a variable of type:
double
then you can assign to it any value of primitive
numeric typefloat
then you can assign to it any value of primitive
numeric type except double
long
then you can assign to it any value of primitive
integer typeint
then you can assign to it any value of primitive
integer type except long
short
then you can assign to it only values of
type short
byte
then you can assign to it only values of
type byte
char
then you can assign to it only values of
type char
Occassionally, you will want to explicitly perform a widening conversion. For example, suppose you wanted to compute the average of three integers:
public class Average1 { public static void main(String[] args) { int num1 = 10; int num2 = 11; int num3 = 12; int nValues = 3; // the number of values to average double avg = (double) (num1 + num2 + num3) / nValues; System.out.println(avg); } }
Java evaluates the average in the example above by
(num1 + num2 + num3)
as an
int
(because num1
, num2
,
and num3
are all of type int
).double
double
divided by an int
so the value of nValues
is converted to double
double
values to compute the average
Occassionally, you will want to explicitly perform a
narrowing conversion. An example is when you compute a
quantity using double
that is supposed to
represent an integer quantity, like the number of hairs
on a human head:
// recall that areaCovered is a double int numberOfHairs = (int) (areaCovered * density);
Casting a double
to an int
or
long
discards the decimal part of the number
(it does not round); thus, the cast
int someValue = (int) 5.99;
results in someValue
having a value of 5
.
If you want to round the result you need to use a
method from java.lang.Math
.
In 1020, the client is you, the programmer of the main
method. You are called a client because you will need to shop for
components that can provide you with services that can help you
solve a programming problem.
We have already used one component named System.out
;
that component provided us with a service named println
that let us send output to a console.
In Java, a component that provides a service is usually what we call an object; occassionally, the component is something else called a utility.
As the client, you can choose to entrust information (data) or computation to an object or utility.
What are some advantages of delegating data storage?
What are some advantages of delegating computation?