Incremental Java
Boxes Have Types

Boxes Have Types

So far, we've restricted boxes to holding whole numbers. In math, whole numbers are integers.

However, we're going to want to write programs where we have fractions. Much of scientific computations works with real numbers (in reality, we use approximations to real numbers called floating point numbers).

We also write programs where we work with "words". When you use a word processor, you type in words. They don't have to be real words. You can make up words, or use punctuation in funny ways like #$?!!.

We want boxes to store words or characters as well.

One way to do this is to allow boxes to store anything. Any box can hold a value that's an integer or a real number or a word or a character.

However, this creates problems when keeping track of what's going on. For example, suppose box 2 holds the name of a person, but you forget that, and put in a number instead. If you allow a box to store any kind of value, you can accidentally put in values you didn't mean to.

Each box is going to have a type, which restricts the kind of values the box can hold. This restriction makes it easier to avoid errors, though clearly, we can't always avoid errors.

What is a Type?

For now, a type is a set of values. For example, if we could create a type called integer which is the set { ..., -3, -2, -1, 0, 1, 2, 3, ... }.

A box with type integer can only hold one value from this set at a time. However, we can change the value by writing a new value to the box.

In Java and all programming languages, types are finite sets. They can't be infinite. We'll look at the basic types in Java in the next lesson.

Int Types

When you buy a computer, one of the first things you should consider is the amount of RAM. Typical values for RAM is maybe 256 Megabytes of RAM.

We've been talking about boxes. Where are these boxes really located? To a first approximation, we can say these boxes are in RAM. The problem with RAM is that it's finite. 256 M of RAM is a lot, but it's not infinite.

Integers, on the other hand, can be infinitely long (or approach infinity, to be accurate). Thus, memory can never store arbitrary integers.

We must place limits on how big an integer.

This isn't so strange. Think about the car odometer. Most of them only allow up to 6 or 7 digits. For 6 digits, the range of mileage is from 0 up to 999,999. We can't have an infinite number of digits. We pick 6 or 7 because that seems like a reasonable value. Cars usually don't last to a million miles (some do, but it's rare). Thus, there's no need to make it 10 digits long or longer.

Similarly, we want to have enough digits (actually, bits, which store 0 or 1) so that we can store large numbers, but not so large that it becomes unwieldy to use.

For Java, int values use 32 bits. The range of values is from roughly negative 2 billion up to positive 2 billion. That may not seem like a very large range, but you'd be surprised how few computations that we'll work with get beyond a few thousand.

The key point to know about int is that it has a range. There is a maximum magnitude negative value and a maximum magnitude positive value.

(The exact range is -231 up to 231 - 1, inclusive, if you're really curious).

Double Types

One problem with int is that it can only represent integers. We need something like real numbers.

Computers can't represent mathematical real numbers. Like integers, real numbers can be infinitely large. Computers, having finite memory, can't store infinite sized real numbers. They can't even store extremely large real numbers.

There's a second problem. Real numbers can have an infinite number of digits after the decimal point. Again, computers have finite memory, so you can't store real numbers to infinite precision.

Computers use floating point notation to store real numbers. If you've taken a course in chemistry or physics, you should have studied exponential or scientific notation.

You write numbers like 2.3 x 103. 2.3 is called the mantissa. In scientific notation this number must be greater than or equal to 0, but less than 10. 3 is the exponent. It can be any value.

In Java, the type of floating point is called double. This is short for "double precision floating point". Doubles have a huge range, from about 10-308 to 10308. That's 10 followed by 300 zeroes. It's more than you really need.

Why Int?

Now you might ask yourself why bother with int. Doesn't double handle both?

Several reasons we use int. First, int uses less space. One int uses up 32 bits, while one double uses 64 bits.

Second, the hardware for doing multiplication and addition is quicker for int than double. Although you're not likely to notice the speed difference, a program using lots of floating point multiplications would be slower.

Third, int is more precise. As long as you stay in between the minimum and maximum value, you have precise arithmetic using int. double, on the other hand, has missing numbers. In particular, recall we can only have a finite number of digits after the decimal point.

Just to illustrate the concept. Suppose we could only use 3 digits past the decimal point. Then, both 3.1442 and 3.1443 (both of which have 4 digits past the decimal point) would be stored in a computer as 3.144. We had to get rid of the fourth digit because there was no space. This introduces a tiny error.

If you do computations in a bad way, this error begins to magnify.

This doesn't happen with int, provided you don't need to use fractions.

The rule of thumb is: use int if possible, and double only if necessary.