taylorialcom/ Fundamentals

Java Primitive Types

Java primitives are types that are built into the Java language. When a primitive is declared, a fixed amount of memory is reserved on the stack to store its value.

Primitives represent integer values, floating-point values, character values, and boolean values.

Integer Types

The declaration int number; causes four bytes to be reserved on the stack to store a signed integer value that is no smaller than -2,147,483,648 and no larger than 2,147,483,647.

Similarly, byte number; causes one byte to be reserved on the stack to store a signed integer value. Since one byte contains eight bits, there are 256 unique combinations of eight zeros and ones. Since a byte represents a signed integer, a byte can represent an integer value no smaller than -128 and no larger than 127. The range of the int type is a result of the number of unique values that can be represented by 32 bits.

The table below shows the amount of space used to store each primitive integer type and the range of values that each type can represent.

byte8 bits\( -128 \)\( 127 \)
short16 bits\( -32,768 \)\( 32,767 \)
int32 bits\( -2,147,483,648 \)\( 2,147,483,647 \)
long64 bits\( \approx -9 \times 10^{18} \)\( \approx 9 \times 10^{18} \)

Floating-Point Types

Java has two primitive types that can store floating-point values, i.e., values containing a decimal place. The bits used to represent a floating-point number of split into three groups. As a crude approximation, one bit is used to indicate whether the number is positive or negative. The remaining bits are divided into two sets. One set of bits represents the actual digits in the number while the other set of bits represents the location of the decimal place. If we have more bits for the first set, we get more digits of precision.

float32 bits6 digits\( \approx 1.2 \times 10^{-38} \)\( \approx 3.4 \times 10^{38} \)
double64 bits15 digits\( \approx 2.2 \times 10^{-308} \)\( \approx 1.8 \times 10^{308} \)

More precisely, the representation of float follows the IEEE 754 standard which specifies that the first bit represents the sign (0 for possitive and 1 for negative). The next eight bits represent the exponent. The last 23 bits hold the mantissa, a.k.a, the significand. This results in a float representation of: \( sign \times mantissa \times 2^{exponent} \). Even this is a bit of a simiplication. More details are available here or here. A double uses 52 bits for the mantissa and 12 bits for the exponent.

Float Toy is a nice tool lets you develop an understanding by twiddling bits and seeing how it changes the value being represented. If you have more interest, the Game Engine Black Book: Wolfenstein 3D has a nice visualization of how these values are stored.

Automatic Type Conversions

Java will automatically convert from one primitive type to another in certain situations. For example, 3 + 3.8 requires an int and a double to be added. Before the addition can take place both addends must be of the same type. In this case, Java automatically promotes the int literal 3 to a double (3.0) and then performs the addition. Whenever one primitive type is available, but another primitive type is needed, a check is automatically performed to see if automatic type conversion is possible. If it is not possible, a compiler error generated.

The following figure shows which automatic type conversions are possible. If the primitive available is to the left of the primitive that is required, automatic type conversion is done.

Some examples:

byte b = 22;
char c = 'a';
short s = 3333;
int i = 44444;
long l = 5555555555L;
float f = 6.67F;
double d = Math.PI;
i = c; // VALID: char left of int
l = f; // INVALID: float NOT left of long
d = b; // VALID: byte left of double
f = i + c; // VALID: char left of int -> result of addition is int which is left of float

Charater Type

The char primitive represents a single character. Sixteen bits are used to represent chars following the 16-bit Unicode standard. Java will automatically convert a char to any type that a short can be automatically converted to, but no primitive time will be automatically converted to a char.

Boolean Type

The boolean primitive represents a true/false value. It can be stored in as little as one bit. Java does not perform any automatic type conversions on the boolean type.