Viliam Búr

2008/08/03

Integer Numbers in Java

In programming language Java there are four primitive types designed for work with integers: byte, short, int, and long. These are signed integer numbers with size 1, 2, 4, 8 bytes, that is 8, 16, 32, 64 bits. (Also char type designed for work with characters is a 16-bit unsigned integer, and we can use it for mathematical operations, but for the sake of program legibility I do not recommend doing this needlessly.)

Basic mathematical operations are done using symbols: "+" addition, "-" subtraction, "*" multiplication, "/" integer division, "%" integer division reminder.

int a = 100;
int b = 6;

System.out.println(a + b);  // 106
System.out.println(a - b);  //  94
System.out.println(a * b);  // 600
System.out.println(a / b);  //  16
System.out.println(a % b);  //   4

The "+" symbol means not only addition but also string concatenation, and it has the same priority as mathematical "+" and "-". If you display calculated results accompanied by text description, take care about the operator priority, and use parentheses around the calculation.

int x = 2;
int y = 3;

System.out.println("Sum is " + x + y);    // Sum is 23
System.out.println("Sum is " + (x + y));  // Sum is 5

We can compare numbers using operators: "==" is equal, "!=" is not equal, "<" is less, ">" is more, "<=" is less or equal, ">=" is more or equal.

int x = 2;
int y = 3;

if (x == y) {
 System.out.println("X is equal to Y");
}
if (x != y) {
 System.out.println("X is not equal to Y");
}
if (x < y) {
 System.out.println("X is less than Y");
}
if (x > y) {
 System.out.println("X is more than Y");
}
if (x <= y) {
 System.out.println("X is less than or equal to Y");
}
if (x >= y) {
 System.out.println("X is more than or equal to Y");
}

Each of these primitive types corresponds to an object type: java.lang.Byte, java.lang.Short, java.lang.Integer, java.lang.Long; these types are subtypes of abstract type java.lang.Number. Using object types we can use integers in contexts where objects are required, such as sets or lists. The object types provide also some useful static methods. A primitive value can be converted to object using static method valueOf; an object can be converted to primitive value using methods byteValue, shortValue, intValue, longValue.

int i = 5;
Integer j = Integer.valueOf(i);
int k = j.intValue();

System.out.println(i);  // 5
System.out.println(j);  // 5
System.out.println(k);  // 5

Java supports autoboxing, that is automatical insertion of methods converting primitive values to objects and vice versa. The previous example could have been written more simply, but it would be the same thing.

int i = 5;
Integer j = i;
int k = j;

System.out.println(i);  // 5
System.out.println(j);  // 5
System.out.println(k);  // 5

Be careful about autoboxing. It is better to use the methods explicitly, because it helps us avoid errors which are very difficult to spot. An "Integer" variable can contain null value, an "int" variable always contains some number; if we forget this, the automatic conversion may throw a NullPointerException.

When using "Integer" and "int" types the meaning of "==" symbol is different. For primitive types the "==" symbol compares the numbers. For object types the "==" symbol tests if it is the same object instance. So if we have two different objects containing the same number, the "==" symbol will return false, because they are different; to compare their contents we have to use "equals" method. With two different primitive types, for example "int" and "long", the "==" symbol compares if they contain the same number; for "Integer" and "Long" objects the "equals" method always returns false. When using objects for numbers, we have to be very careful about what exactly are we comparing.

(C) 2008 Viliam Búr viliambur.blogspot.com

int i = 5;
int j = 5;
if (i == j) {  // yes
 System.out.println("I and J are equal");
}

Integer I = new Integer(5);
Integer J = new Integer(5);
if (I == J) {  // no
 System.out.println("I and J are the same object");
}
if (I.equals(J)) {  // yes
 System.out.println("I is same as J");
}

int x = 5;
long y = 5;
if (x == y) {  // yes
 System.out.println("X and Y are equal");
}

Number X = new Integer(5);
Number Y = new Long(5);
if (X == Y) {  // no
 System.out.println("X and Y are the same object");
}
if (X.equals(Y)) {  // no!
 System.out.println("X is same as Y");
}
if (X.longValue() == Y.longValue()) {  // yes
 System.out.println("X and Y are equal");
}

We can calculate the range of each integer type from their number of bytes, or we can use their static variables "MIN_VALUE" and "MAX_VALUE".

System.out.println("Byte " + Byte.MIN_VALUE + " " + Byte.MAX_VALUE);
// Byte -128 127
System.out.println("Short " + Short.MIN_VALUE + " " + Short.MAX_VALUE);
// Short -32768 32767
System.out.println("Integer " + Integer.MIN_VALUE + " " + Integer.MAX_VALUE);
// Integer -2147483648 2147483647
System.out.println("Long " + Long.MIN_VALUE + " " + Long.MAX_VALUE);
// Long -9223372036854775808 9223372036854775807

If we want to write the number into string, we can use the "toString" method (it has also a static version) or use the "+" symbol to append the number to a string (for example, an empty string). If we want to use other than decimal numeral system, we can use static method "toString" with two parameters. The numeral system base cannot be larger than "Character.MAX_RADIX", but we usually need bases from 2 to 16, and these are allright. For frequently used bases there are also static methods "toBinaryString", "toOctalString", "toHexString" which convert an unsigned number as a parameter.

int x = 123456789;
System.out.println(Integer.toHexString(x));   //  75bcd15
System.out.println(Integer.toString(x, 16));  //  75bcd15

int y = -123456789;
System.out.println(Integer.toHexString(y));   // f8a432eb
System.out.println(Integer.toString(y, 16));  // -75bcd15

If we want to read number from a string, we can use static method "parseInt" ("parseByte",...) or "valueOf", depending on whether we need a primitive type or an object. (If the string contains unsigned number, for example returned by method "toHexString", there can be a range overflow and a "NumberFormatException".)

System.out.println(Integer.parseInt("cafe", 16));  // 51966

We can also perfrom bit operations on integers: "&" conjunction (both bits), "|" disjunction (at least one bit), "^" exclusive disjunction (exactly one bit). We can shift bits using operators: "<<" left shift, ">>" sign preserving right shift, ">>>" zero filling right shift.

int i = Integer.parseInt("0011", 2);
int j = Integer.parseInt("0101", 2);

System.out.println(Integer.toBinaryString(i & j));  // 0001
System.out.println(Integer.toBinaryString(i | j));  // 0111
System.out.println(Integer.toBinaryString(i ^ j));  // 0110

int k = -100;

System.out.println(Integer.toBinaryString(k));
// 11111111111111111111111110011100
System.out.println(Integer.toBinaryString(k << 1));
// 11111111111111111111111100111000
System.out.println(Integer.toBinaryString(k >> 1));
// 11111111111111111111111111001110
System.out.println(Integer.toBinaryString(k >>> 1));
// 01111111111111111111111111001110

We can receive random numbers using object java.util.Random. Here is a dice throwing simulation:

java.util.Random r = new java.util.Random();
for (int i = 0; i < 100; i++) {
 System.out.println(1 + r.nextInt(6));
}

Related articles:

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home