3 - Data Types
3 - Data Types
Java is a strongly typed programming language implying that all variables must have a
declared data type. There 8 primitive data types in Java. Of the 8, four are integer types;
two are real or floating-point number types; one is the character type char used for code
units in Unicode encoding scheme and one is a boolean type for truth tables.
The most commonly used types for general purpose programming are int and double.
Integers
Integers are positive and negative numbers without fractional parts. Unlike in C/C++ the
ranges of the integer types are independent of the machine on which you will be running
the code.
Note that long integer numbers have a suffix L for example 10 567 890 46L
Decimal: Base 10, whose digits consists of the numbers 0 through 9; this is the number
system you use every day
Hexadecimal: Base 16, whose digits consist of the numbers 0 through 9 and the letters A
through F. The prefix 0x indicates hexadecimal for example 0xDFAC.
Floating-Point types
Floating-point numbers have fractional parts and here we have double and float as
floating–point types.
Doubles are often called double precision numbers because they have twice the precision
of the float type.
float type numbers have a suffix F or f for example 6.789F. Whereas it is mandatory to
suffix float type numbers with F it is optional to suffix double type numbers with D or d.
The floating point types (float and double) can also be expressed using E or e (for
scientific notation), F or f (32-bit float literal) and D or d (64-bit double literal; this is the
default and by convention is omitted).
double d1 = 123.4;
double d2 = 1.234e2;
float f1 = 123.4f;
In Java SE 7 and later, any number of underscore characters (_) can appear anywhere
between digits in a numerical literal. This feature enables you, for example to separate
groups of digits in numeric literals, which can improve the readability of your code.
For instance, if your code contains numbers with many digits, you can use an underscore
character to separate digits in groups of three, similar to how you would use a
punctuation mark like a comma, or a space, as a separator.
The following example shows other ways you can use the underscore in numeric literals:
float pi = 3.14_15F;
You can place underscores only between digits; you cannot place underscores in the
following places:
Prior to an F or L suffix
The following examples demonstrate valid and invalid underscore placements (which are
highlighted) in numeric literals:
// prior to an L suffix
// OK (decimal literal)
int x1 = 5_2;
int x2 = 52_;
// OK (decimal literal)
int x3 = 5_______2;
int x4 = 0_x52;
int x5 = 0x_52;
// OK (hexadecimal literal)
int x6 = 0x5_2;
Character Type
The char is two bytes long, allowing for 65 536 different characters, compared to the one-
byte ASCII code which allows only 255 different characters. The encoding scheme used
is Unicode. The first 255 characters in Unicode are the same as ASCII. Keyboard
characters may be represented as literal characters in single quotes ‘c’; but in general
Unicode characters are represented as ‘\uhhhh’, with single quotes, \u and four hex digits
with leading zeros. Eg N = ‘\u004E’
Methods are provided for converting between Unicode and other encoding schemes such
as ASCII in Microsoft windows.
The ‘\’ backslash character is used to escape or give the next character a special meaning;
these escape sequences include:
System.out.print(“n \n \\n”);
Outputs
\n
Variables
Variable names may include digits, letters, $, and _ and may not start with a digit. Java is
strongly typed and every variable must be declared before use. Every variable should be
initialized before use and the compiler will try to prevent the use of uninitialized
variables.
int i ; // declaration
i = 10; // assignment
Usually declaration and assignment are combined into a definition:
When the declaration is made, memory space is allocated to store the value of i.
Variable scope
The scope of variables is from the point of declaration to the end of the block in which
they are declared.
{
int i =1;
System.out.println(i);
}
{
int i = 2;
System.out.println(i);
}
Variables can not be declared in overlapping blocks.
{
int i =1;
System.out.println(i);
{
int i = 2; // error
System.out.println(i);
}
}
Constants
Primitive types
The storage allocated to primitive types is defined in the language specification rather
than being left to the language implementer.
There are six numerical data types: byte, short, int, long, float, and double.
At the time a variable is declared, it also can be initialized. For example, we may
initialize the integer variables count and height to 10 and 34 as
Type conversion
int x = 1;
double d = 4.567;
d = x ; // OK
x = d; // Error
Note that (int) truncates floating point values. To round floating point values use the
Math.round() method of the Java Math library, but since this returns a long value you
have to cast the result to integer:
int x = (int)Math.round(d);
Note that when you use explicit casts, you are expected to know what you are doing, for
example, the following cast is legal but not sensible:
System.out.println(b); // prints -1
System.out.print(“n \n \\n”);
Outputs
\n
Assignment Operator
Assigning a value to a variable seems straightforward enough; you simply assign the stuff
on the right side of the = to the variable on the left.
Casting
Involves converting values from one type to another. It can be explicit or implicit. An
implicit cast means you don't have to write code for the cast; the conversion happens
automatically. Typically, an implicit cast happens when you're doing a widening
conversion, i.e., when putting a smaller thing into a bigger container. For example:
int a = 100;
long b = a; // Implicit cast, an int value always fits in a long
Operators
Operation Operator
Addition +
Subtraction -
Multiplication *
Division /
Modulus (for remainder) %
Arithmetic Expression
x+3*y
Sub expressions ( )
unary + -
multiplicative operators * / %
additive + -
assignment =
In Java operator and assignment may be combined in expressions with only one
variable. For example:
y= y + 6; can be expressed as
y += 6;
int m = 7;
int n = 7;
int a = 2*++m; // mow a is 16, m is 8
int b = 2*n++; // now b is 14, n is 8
5/3 evaluates to 1
If at least one of the numbers is floating point then division includes the remainder:
5.0/3
5/3.0
5.0/3.0
5/ (double)4
All evaluate to 1.75
The usual precedence relations hold; use parentheses to override these if necessary.
The conditional operator is a ternary operator (it has three operands) and is used to
evaluate boolean expressions, much like an if statement except instead of executing a
block of code if the test is true, a conditional operator will assign a value to a
variable.
In other words, the goal of the conditional operator is to decide which of two values
to assign to a variable. This operator is constructed using a ? (question mark) and a :
(colon). The parentheses are optional. Its structure is:
You can read the preceding code as Set numOfPets equal to 3. Next we're going to
assign a String to the status variable. If numOfPets is less than 4, assign "Pet limit not
exceeded" to the status variable; otherwise, assign "too many pets" to the status
variable. A conditional operator starts with a boolean operation, followed by two
possible values for the variable to the left of the assignment (=) operator. The first
value (the one to the left of the colon) is assigned if the conditional (boolean) test is
true, and the second value is assigned if the conditional test is false. You can even
nest
conditional operators into one statement:
class AssignmentOps {
public static void main(String [] args) {
Bitwise operators
Bitwise operators are used with integer types and they work directly with the bits that
make up the integers.
Here follows the operators:
1. and (&)
2. or (|)
3. xor (^)
4. not (~)
5. shift left (<<)
6. shift right (>>)
Of the six logical operators listed above, three of them (&, |, and ^) can also be used as
"bitwise" operators. Here are several legal statements that use bitwise operators:
byte b1 = 6 & 8;
byte b2 = 7 | 9;
byte b3 = 5 ^ 4;
System.out.println(b1 + " " + b2 + " " + b3);
System.out.println(b1<< 2); // shifts by 2 bits to the left
System.out.println(b2 >> 1); // shifts by 1 bit to the right
Bitwise operators compare two variables bit by bit, and return a variable whose bits have
been set based on whether the two variables being compared had respective bits that were
either both "on" (&), one or the other "on" (|), or exactly one "on" (^). By the way, when
we run the preceding code, we get
0 15 1
0
7
It has been said that && and || are short-circuit, however; & and | are not. The example
below illustrates the difference.
int z = 5;
if(++z > 5 || ++z > 6) z++;// z = 7 after this code
versus:
int z = 5;
if(++z > 5 | ++z > 6) z++; // z = 8 after this code
As we can see, usually if a floating-point number is compared with an integer and the
values are the same, the == operator returns true as expected.
y = y - 6;
x = x + 2 * 5;
Now, with compound operators:
y -= 6;
x += 2 * 5;
The last two assignments give the same result as the first two.
These are all static methods of the Math class. Methods which do not apply to objects
must be declared static. Numbers are not objects so the methods of the Math class which
apply to them are static. All methods must belong to a class. The name of the class the
methods belong to must be given so that the compiler can locate them.
abs
It strips off the sign of a number and returns it simply as a number. Thus the following
will simply print out 99. If the number is not negative you just get back the same number.
ceil
This method returns the next whole number up that is an integer. Thus if you pass
ceil(1.1)
ceil(-1.1)
floor
Returns the largest (closest to positive infinity) double value that is not greater than the
argument and is equal to a mathematical integer.
If that is not entirely clear, here is a short program and its output
-100.0
-99.0
99.0
-1.0
0.0
Take note of the following two methods as they take two parameters. You may get
questions with faulty examples that pass them only one parameter. As you might expect
these methods is the equivalent of
-1
2
1
-10
1
random
Unlike some random number system Java does not appear to offer the ability to pass a
seed number to increase the randomness. This method can be used to produce a random
number between 0 and 100 as follows.
One of the important aspects of this method is that the value returned is between 0.0 and
1.0. Thus a typical sequence of output might be
0.9151633320773057
0.25135231957619386
0.10070205341831895
Often a program will want to produce a random number between say 0 and 10 or 0 and
100. The following code combines math code to produce a random number between 0
and 100.
System.out.println(Math.round(Math.random()*100));
round
Rounds to the nearest integer. So, if the value is more than half way towards the higher
integer, the value is rounded up to the next integer. If the number is less than this the next
lowest integer is returned. So for example if the input to round is x then :
System.out.println(Math.round(1.01));
System.out.println(Math.round(-2.1));
System.out.println(Math.round(20));
1
-2
20
These trig methods take a parameter of type double and do just about what trig functions
do in every other language you have used.
sqrt
Overflow
For effectively unlimited range use BigInteger and BigDecimal in the java.Math
class.
Precision
With floating point storage, precision is also an important consideration. Float values
provide approximately 7 significant digits and double values provide approximately 15
significant digits. Arithmetic can lead to loss of precision:
Calculations with floating point numbers also suffer from round off errors. With
manual calculator and decimal representation, for example, 1/3 with two-decimal
place precision is 0.33, so 1/3*3 is 0.99 not 1.00. With computers and binary
representation round off also occurs:
double f = 4.35;
int n = (int)(100*f); // should be 435
System.out.println(n); // prints 434!
In the binary system there is no exact representation for 4.35, just as there is no exact
representation for 1/3 in the binary system and the binary representation of 4.35 is
slightly less than 4.35 so 100 times that value is slightly less than 435, and the (int)
cast truncates the value and discards the fractional part. Rather use rounding than
truncation. The Math.round() method returns a long value which can be safely cast
into int;
int n = (int)Math.round(100*f);
System.out.println(n); // prints 435