Numeric Result Type


You have now learned about all of Java's unary and binary operators. Before closing this chapter, you need to learn about more topic: the result type of numeric operations.

Clearly, it would be inconvenient to prohibit operating on mixed types. You may find yourself doing arithmetic on two numbers, one of which might be an int and the other of which might be a float. The next issue to consider is the data type of the result.

Java's rules for determining the type of the result are based on the concept of width. As you saw in Chapter 2, every numeric type has a range. This is shown in Table 3.4.

Table 3.4: Ranges of Numeric Types

Name

Size

Minimum Value

Maximum Value

byte

8 bits

-128

127

short

16 bits

-32768

32767

char

16 bits

0

65535

int

32 bits

-2147483648

2147483647

long

64 bits

-9223372036854775808

9223372036854775807

float

32 bits

-3.4x1038

3.4x1038

double

64 bits

-1.8x10308

-1.8x10308

If the range of any type completely contains the range of another type, the first range is considered to be wider than the second range. If a range is completely contained within another range, the first range is narrower than the second range. Table 3.4 shows that the byte type is narrower than the short type. Note that some types are neither wider nor narrower than some other types. Short, for example, is neither wider nor narrower than char.

Figure 3.12 illustrates data type width. Figure 3.12 is definitely not drawn to scale. If the line representing double were scaled to the line representing byte, the double line would be 5x10275 light years long. I really wanted to print the line to scale, because I believe accuracy is important, but my editor pointed out that the line would be 3 x 10273 times the diameter of the universe. The publisher was unwilling to pay for that much ink, and economics won out.

click to expand
Figure 3.12: Data type width, not to scale

Another way to imagine width is shown in Figure 3.13. A type is wider than another type if you can get from the first type to the second type by following the arrows. So double is wider than byte, and long is wider than char.

click to expand
Figure 3.13: Data type width relationships

Figure 3.13 shows that float is wider than long, even though longs are 64 bits and floats are only 32 bits. That might seem backwards, but you'll see why it's true if you think about the definition of "wider." If you don't feel like thinking about that right now, you can wait until you get to Exercise 6.

Java's rule for the result data type is this: It's either int or the type of the widest operand, whichever is wider. This means that the result of any arithmetic operation will never by a byte, short, or char.

This rule applies to unary as well binary operations. For example, if s is a short, -s is an int.

Table 3.5 summarizes the result type combinations for binary operations.

Table 3.5: Binary Arithmetic Result Types

byte

short

char

int

long

float

double

byte

int

int

int

int

long

float

double

short

int

int

int

int

long

float

double

char

int

int

int

int

long

float

double

int

int

int

int

int

long

float

double

long

long

long

long

long

long

float

double

float

float

float

float

float

float

float

double

double

double

double

double

double

double

double

double

It is important to know about arithmetic result types because of another rule: You can only assign a numeric value to a variable whose type is the same as, or wider than, the type of the numeric value. If you try to do anything else, the compiler will generate an error. This makes sense, because you might be trying to store a value that the variable cannot represent. For example, you can't store a long value in a byte variable, because the long value might be greater than 127 or less than -128. So the following code fragment will generate a compiler error:

long distance = 999999; long time = 5000; byte rate = distance / time;

This rule sometimes gets in your way when you just want to initialize a variable with a literal value. Java dictates that all floating-point literals are doubles, and all integral literals are ints. So 3.14 and 2.5e33 are both doubles, and 1234 is an int.

If you try to assign a value like 3.14 to a float (such as float f = 3.14;), the compiler will complain that you are trying to assign a double to a float. To fix the problem, append the letter f or F to the end of the literal number. This will tell the compiler that the literal is really a float:

float f = 3.14f; // Or 3.14F

The situation is a bit stranger if you try to assign a big literal value to a long variable. The following line generates a compiler error:

long timeAgo = 999999999999; // 12 digits

The 12-digit string of 9s is too big to be represented by an int. Even though you innocently want to assign a big number to a long variable, behind the scenes the compiler is going to try to create an int to store the value 999999999999. This is because the compiler uses ints to store literal integral numbers. To get around the problem, append the letter l or L to the literal value to indicate that it's really a long:

long timeAgo = 999999999999L;

You could also use 999999999999l, but a lowercase l looks too much like a 1. The uppercase version is definitely preferable.

What happens when you want to assign a literal value to a byte, short, or char variable? In this case, the compiler gives you a break. As long as the literal value falls within the variable's range, statements such as these are legal:

byte x = 12; short y = -22; char z = 0;




Ground-Up Java
Ground-Up Java
ISBN: 0782141900
EAN: 2147483647
Year: 2005
Pages: 157
Authors: Philip Heller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net