Previous lesson Back to the front Next lesson

A Numerical Character


In this lesson, we're going to look at the remaining seven primitive types - you might remember a table with some quite large numbers (!) in it. We've spent a lot of time on boolean, in this lesson we intend to explain the remainder. One of these is char (meaning character) and the others are all types of numbers, hence the title.

Type Size Minimum Value Maximum Value
char 16 bits \u0000 \uFFFF

So then, char is short for character. A character is a letter or number, or a space, or a tab, or a special new line character, or a symbol like '?'. I hope that in the lessons about boolean I managed to get across the point that you can treat a boolean much like an int, and the same is true of a char.


class Hello {
	public static void main(String[] args) {
		char c;
		c = 'B';
		System.out.println("The value of c is " + c);
 	}
}

Here we've created a variable of type char called c. In the second statement we've set its value to the character capital B. Notice that the B is surrounded by single quote marks rather than the double quotes used for a string (the single quote is the same key as @ but without pressing shift). So if you write 'B' then you get a character, but if you write "B" then you get a String which has a length of one. They are not the same thing - you can't write 'BC' because single quotes can only be used for one character.

A character in single quotes like this is a character literal, just as 2 is a integer literal and true is a boolean literal. In the third statement, the value of the character c is printed to the screen.

[nurmes]btg: javac Hello.java
[nurmes]btg: java Hello
The value of c is B
[nurmes]btg: 

It's not a terribly exciting program. Sorry.

You can also specify a character using a four-digit hexadecimal number. If you don't know what a "four-digit hexadecimal number" is, my advice is not to worry about it. I can't think when you would do this, unless you wanted to write a foreign character and you didn't have a key for it on your (English) keyboard. Anyway, here it is:


class Hello {
	public static void main(String[] args) {
		char c;
		c = '\u0042';
		System.out.println("The value of c is " + c);
 	}
}

The "four-digit hexadecimal number" is 0042. This is the code for capital B. In case you were wondering. Don't get in a stress about it, we'll come back to it in a later lesson and it's not at all important for now.

[nurmes]btg: javac Hello.java
[nurmes]btg: java Hello
The value of c is B
[nurmes]btg: 

You can also add characters together - this turns them into a string, which is a sequence of zero or more characters.


class Hello {
	public static void main(String[] args) {
		char c;
		c = '\u0042';

		char c2 = 'e', c3 = 'n';
		System.out.println("My name is " + c + c2 + c3 + '!');
 	}
}

We've added together a string ("My name is "), the values of c ('B') and c2 ('e') and c3 ('n'), and a character literal ('!'). Here's the result:

[nurmes]btg: java Hello
My name is Ben!
[nurmes]btg: 

That's enough characters I think. I'm itching for an integer!

Type Size Minimum Value Maximum Value
byte 8 bits (or 1 byte, surprisingly) Byte.MIN_VALUE (this is -27, or -128) Byte.MAX_VALUE (this is 27 - 1, or 127)
short 16 bits (or 2 bytes) Short.MIN_VALUE (this is -215, or -32768) Short.MAX_VALUE (this is 215 - 1, or 32767)
int 32 bits (or 4 bytes) Integer.MIN_VALUE (this is -231, or -2 147 483 648) Integer.MAX_VALUE (this is 231 - 1, or 2 147 483 647)
long 64 bits (or 8 bytes) Long.MIN_VALUE (this is -263, or -9 223 372 036 854 775 808) Long.MAX_VALUE (this is 263 - 1, or 9 223 372 036 854 775 807)

What these all have in common is that they are all whole numbers which can be positive or negative. You've met int already. A byte has a small range - you might use it to store the amount of money in your bank, for example. A short has a larger range because it is 16 bits rather than 8 - you might use it for storing the size of your overdraft. As you can see from the table, an int can store pretty big numbers, like the time (in hours) it took you to complete Practical 2. A long can store really huge numbers. To give you an idea, the clock in Java is stored as a long value; the time, in thousandths of a second, since midnight on January 1st, 1970. It's had a unique value every thousandth of a second since 1970 and it will go on having unique values when you are long dead (sorry, no pun intended again). You can measure your age in thousandths of a second easily with a long.

Now all these values, from the teeny byte to the huge long, are stored in the same way - as a signed (positive or negative) whole number. The accuracy for all of them is to the nearest whole number. And no nearer. When you divide with any of these, the answer is rounded down (remember much earlier that 12/7 comes to 1).

If you think about it, it is possible to convert any number stored as a byte to a short. Why? Well, a byte can only store numbers between -127 and 128. All these numbers (and more) can be represented by a short, which has a larger positive and negative range. In the same way, a byte can also be converted to an int or a long. In fact you can also turn a short into an int or a long. Or an int can be converted to a long. Look at the table above and convince yourself of this. We think of these conversions as "safe", because the value will always be the same after being converted as it was before.

You can also go from a type with a larger to a smaller range, for example a short to a byte, provided you know that the value in the short variable is always between -127 and 128 so that it will "fit" in a byte. If it is outside this range, the value will be rounded so it lies in the range. These conversions are "unsafe", because sometimes the value will be different after being converted.

For the moment, that's all you need to know about these four whole number types. We'll come back to exactly how the computer represents these numbers in a later lesson. On to the last two types!

Type Size Minimum Value Maximum Value
float 32 bits (or 4 bytes) Float.MIN_VALUE (this is 1.4 x 10-45, or about 0.000 000 000 000 000 000 000 000 000 000 000 000 000 000 001 401 298 464 324 817 070 923 729 583 289 916 131 28). Float.MAX_VALUE (this is 3.4 x 1038, or about 340 282 346 638 528 859 811 704 183 484 516 925 440).
double 64 bits (or 8 bytes) Double.MIN_VALUE (this is 4.9 x 10-324, or about 0.000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 004 940 656 458 412 465 441 765 687 928 682 213 723 650 598 026 143 247 644 255 856 825 006 755 072 702 087 518 652 998 363 616 359 923 797 965 646 954 457 177 309 266 567 103 559 397 963 987 747 960 107 818 781 263 007 131 903 114 045 278 458 171 678 489 821 036 887 186 360 569 987 307 230 500 063 874 091 535 649 843 873 124 733 972 731 696 151 400 317 153 853 980 741 262 385 655 911 710 266 585 566 867 681 870 395 603 106 249 319 452 715 914 924 553 293 054 565 444 011 274 801 297 099 995 419 319 894 090 804 165 633). Double.MAX_VALUE (this is 1.8 x 10308, or about 179 769 313 486 231 570 814 527 423 731 704 356 798 070 567 525 844 996 598 917 476 803 157 260 780 028 538 760 589 558 632 766 878 171 540 458 953 514 382 464 234 321 326 889 464 182 768 467 546 703 537 516 986 049 910 576 551 282 076 245 490 090 389 328 944 075 868 508 455 133 942 304 583 236 903 222 948 165 808 559 332 123 348 274 797 826 204 144 723 168 738 177 180 919 299 881 250 404 026 184 124 858 368).

What exactly makes these two types so special anyway (apart from the ridiculous maximum and minimum values)? If you look at the range given, it might give you a clue. The float type has a very big maximum value, but the minimum is 0.0000000000...

Hang on, then - what's going on? Remember that the types we've seen so far can only store whole numbers. The float and double types can deal with numbers with something after the decimal point! In fact, they store numbers in scientific notation. You might remember that from Physics at school - a number like 12345 is written 1.2345 x 104.

A float has a fixed amount of space for the 1.2345 part (called the mantissa) and a fixed amount of space for the 4 in 104 (called the exponent) - in other words the number of significant figures is fixed. To represent tiny numbers close to zero, the exponent has a large negative value. To represent very large numbers, the exponent is large and positive. This means that the number may be represented to less than whole number accuracy, if it is very large.

A double can store more significant figures and has a larger range for the exponent. Hence its maximum is much bigger and its minimum is much smaller compared to float. Both of these types are called floating point numbers (because the decimal point floats up and down). The double type is more precise and is known as double precision. Don't worry about remembering that too much.

That's all the primitive types now. We've learned about two special types (boolean and char) which are both very important. There are also four types of whole numbers (byte, short, int, long) and two types of floating point numbers.

You might well ask at this point why there are so many types of everything. If a long has the largest range then why bother with the others? Well, a long uses 8 times as much space in the computer's memory as a byte does. For one long variable this doesn't matter, but for an array containing tens of thousands of numbers, the amount of space used is much more significant. So it's important to use the smallest type which is sufficient for what we need to do with it.

Also, if double is better than float then what's the point of float in the first place? Well, there is the argument above about space. But also, to do calculations with double takes more time, so our program runs slower. In most programs we don't need the extra precision offered by double so it's best not to use it. An example is a 3D computer game - the calculations are done using float, because if double was used then the game would run much less smoothly for no real advantage.

In a moment onto the next lesson, which introduces objects and how to mess around with them - a really crucial part of Java. First of all please fill out the micro-questionnaire.

But
what
do
you
think?
This lesson was...
What don't you understand? Other comments?
Excellent
OK
Poor
Your email (optional)
Go on to Stringing Along

Too patronising? Too complex? Typing error? Offended by traffic cones? Got a question or something I should add? Send an email to ben_golding@yahoo.co.uk !

visits to this site

The contents of this site are copyright of Ben Golding