Java Data Types - Numeric Data
Written by Ian Elliot   
Article Index
Java Data Types - Numeric Data
Literals and Expressions
Numeric Output

After looking at some of the advanced ideas of classes and objects, we need to return to some simpler topics to make our understanding complete. We need to look more closely at data and, to get things moving, numeric data. 

Modern Java
With NetBeans And Swing

largecover

Contents

  1. Why Java?
  2. Getting started with Java
  3. Introducing Java - Swing Objects
  4. Writing Code
  5. Command Line Programs
  6. User Interface - More Swing
  7. Working With Class
  8. Java Class Inheritance
  9. Java Data Types - Numeric Data
  10. Java Data Types - Arrays And Strings
  11. Building a Java GUI - Containers
  12. Advanced OOP - Type, Casting, Packages
  13. Value And Reference 
  14. Java Lambdas, SAMs And Events

 

We already know about variables and how to store data, but we need to look more closely at what types of data Java works with. In many ways the need to consider the "type" of data is something of a throwback to the early days of computing when we worked very closely with how the data was stored. Back then it mattered how much storage you used and different ways of storing the same data were used simply because of efficiency considerations - why use two bytes when one will do? Today such issues are far less important but we still work with the basic data types that were introduced then.

There are also some more theoretical reasons why we should make use of a range of data types and select the ones that just suit what we are trying to do, but all of this become much clearer after we have seen some real examples.

Just Write Smaller

The big problem that beginners often have is trying to understand why the whole topic of data type exists at all?

After all if you have a form to fill in and it has a space for you to enter your salary there is usually no question about what numeric range can be entered. If you need to write $100,000 per annum and the space is small you simply write smaller. 

This approach doesn't work for a computer. Everything in a computer is stored as a binary number or a sequence of bits to be even more fundamental. Each memory location has a fixed number of bits and this limits exactly what you can store. For example, a single byte of data is just eight bits and this means you can store a bit sequence that you can interpret as a number between 0 and 255 i.e. 00000000 to 11111111. This sounds OK, but what about negative numbers? If you want to store negatives you have to give over half the range to negative numbers and half to positive. That is, you could say 0 to 127 are positive values and 128 to 255 are the negative values, -1 to -127. 

You can see that what you can store in a computers memory depends on how much memory you allocate to the task and how you decide to code or represent the data. How you represent the data also governs what operations you can carryout and how easy they are. 

For example, if you use a single byte to store an eight bit sequence you could use it to code the positive number 0 to 255 and just ignore the possibility that there are negative numbers. Alternatively you could treat the bit sequences as codes for letters of the alphabet from A to Z and a to z plus digits and other symbols. In the first case it makes sense to add and do arithmetic with the bit sequences but in the second case it doesn't really make sense to add the bit pattern for A to the bit pattern for a. 

The way in which simple data is encoded and stored in bit patterns gives rise to the idea of data types. All computer languages provides some standard low level data types which you can use to store values. In each case you need to know what sort of data you can store in any given data type and you need to know what happens if you try to work with different data types. Some times this makes sense and some times it doesn't but you need to know how things work together. 

So to put it simply - primitive data types exist because there is a need to represent all of the data we use in the external world in as bit patterns in a standard way. 

Now we need to meet some primitive data types. 

Numbers

The most primitive data type in any computer language is number.

You can store a number in a variable but there are different formats used to represent a number and each format takes a different amount of storage. We looked at the basics of numeric types in the chapter Java - Command Line Programs, but there is more to say.

The simplest format records a number with no fractional part,  i.e. it stores integers.

When you store an integer you can opt to use one byte, two, four or eight bytes. Obviously the smaller the amount of storage you use the smaller the numerical range you can use.

The standard Java integer data types are:

  • byte 1 byte  -128 to 127
  • short 2 bytes  -32,768 to 32,767
  • int 4 bytes -2,147,483,648 to 2,147,483,647
  • long 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

You can see that the byte is rather restrictive but long should be more than enough for anything - although you will find that in computing nothing is ever big enough.

If you want to use an integer type then the default choice is generally int, which gives a good trade off between efficiency and range.

Use one of the others if you know that the numbers you want to use are going to be outside of the range of int.

You can also select byte or short as a way to tell other programmers what you expect the range of values to be - although documentation or comments would do the job just as well.

To declare a variable of one of the integer types you would use the form:

type variable = initial value;

where the initial value is optional. For example, to declare an int you would use

int myInteger=100;

or

int myInteger;

To declare a byte variable you would use:

byte myByte=127;

If you try to store a value bigger than a variable of a given type can store then you will either be warned at compile time or when you run the program. You can opt to reduce the range or precision of a value so that it will fit into the variable using a cast - more of which later.

In practice the amount of memory a single variable takes up isn't an issue but when you are allocating lots of variable of the same type, in particular when you create an array (see the next chapter) this can become an issue.

Floating Point

Of course you probably do want to use numeric values that have fractional parts.

The format most often used to store fractional numbers is called "floating point" for reasons that we don't have to go into to make use of it. A floating point variable can store a numeric value with a fractional part but you need to be aware of the range that can be stored and the precision.

Java has two floating point types and trying to pin down the precision and range that they can represent is difficult. Instead it is better to think about the approximate number of digits of precision they provide:

  • float 4 bytes 7 decimal digits
  • double 8 bytes 16 decimal digits

Unless you really need to save storage for some reason using double is and should be the default - 7 digits of precision is not a lot and the extra storage is well worth using.

As in the case of the integer types floating point types are declared using:

float myFloat=0.123;
double myDouble=0.123;

Notice that floating point types are not suitable for recording exact values over a large range such as currency.

If you need to do exact financial calculations then you need to use more advanced data types - such as the BigDecimal class. These are not primitive data types but classes that implement more sophisticated ways of representing and storing numbers.

It is also worth knowing that while numbers are displayed in decimal when you print them out they are in fact stored in binary. This really only causes a problem when we use decimal fractions. The problem is that in any given number base some fractions can be expressed exactly while in other bases the same fractions cannot. For example in decimal you can say that 1/10 is 0.1, exactly but 1/3 is more troublesome because it is 0.33333... going on repeating forever. However in binary 1/10 is  0.0001011101000101110.. repeating forever. Most of the time Java arithmetic gives you the same result that you get when working things out in decimal but you need to be aware that there are differences.

Summary

There are six numeric types four integer and two floating point:

  • byte 1 byte  -128 to 127
  • short 2 bytes  -32,768 to 32,767
  • int 4 bytes -2,147,483,648 to 2,147,483,647
  • long 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,80
  • float 4 bytes 7 decimal digits
  • double 8 bytes 16 decimal digits