Difference between revisions of "Primitives"

From Suhrid.net Wiki
Jump to navigationJump to search
 
(8 intermediate revisions by the same user not shown)
Line 17: Line 17:
 
* Integers are stored in 2 complements's notation
 
* Integers are stored in 2 complements's notation
 
* Leftmost bit is the sign bit, the remaining bits are used to store the value
 
* Leftmost bit is the sign bit, the remaining bits are used to store the value
e.g. of Byte
 
* Byte - 1 byte = 8 bits.
 
* Leftmost bit is to store the sign. So 7 bits are available for the value, so 2^7 = 128 values
 
* Negative range is -128 to -1 (128 numbers)
 
* Positive range is 0 to 127 (128 numbers, 0 is stored as a positive number)
 
* So a byte's range is -2^7 to (2^7 - 1)
 
  
* char's take up 2 bytes
+
* Consider Byte:
 +
** Byte - 1 byte = 8 bits.
 +
** Leftmost bit is to store the sign. So 7 bits are available for the value, so 2^7 = 128 values
 +
** Negative range is -128 to -1 (128 numbers)
 +
** Positive range is 0 to 127 (128 numbers, 0 is stored as a positive number)
 +
** So a byte's range is -2^7 to (2^7 - 1)  - A total of 256 numbers;
 +
 
 +
* Character's take up 2 bytes
 
* they are stored as '''unsigned''' 16-bit integers. This means they will represent a total of 2^16 positive values (0 to 65535 (2^16-1) )
 
* they are stored as '''unsigned''' 16-bit integers. This means they will represent a total of 2^16 positive values (0 to 65535 (2^16-1) )
 
* contrast with short which also uses 2 bytes. But it's max positive range is 2^15 -1. (Since 1 bit is to used to represent the sign)
 
* contrast with short which also uses 2 bytes. But it's max positive range is 2^15 -1. (Since 1 bit is to used to represent the sign)
Line 30: Line 31:
 
== Assignments ==
 
== Assignments ==
  
Watch out!
+
* A literal integer is always implicitly an int.
 +
 
 +
* The compiler will issue an error when it can see that literal value is too large for the variable.
 +
* This can be fixed by explict casting, however if the value is too large - no runtime error will occur - the value will simply "spill" over.
 +
* All the higher order bits are truncated - for e.g. int is 32 bits and byte is 8 bits - so top 24 bits will be chopped off.
 +
 
 +
<syntaxhighlight lang="java5">
 +
 
 +
byte by =  128; //Compiler error
 +
 
 +
byte by = (byte) 128; //OK with explicit cast
 +
System.out.println(by); //Prints -128 after spill over.
 +
 
 +
</syntaxhighlight>
 +
 
 +
* An implicit cast will happen when a widening conversion is being performed.
 +
* So a byte being assigned to int, or an int assigned to a long is OK
 +
 
 +
* An explicit cast is required for narrowing conversions. e.g. float to an int, or a long to an int.
 +
 
 +
<syntaxhighlight lang="java5">
 +
 
 +
long lon1 = 100;
 +
 
 +
int int1 = (int) lon1;
 +
 
 +
</syntaxhighlight>
 +
 
 +
* '''IMPORTANT :''' the result of an expression involving anything int-sized or smaller is always an int. e.g. an operation involving two bytes will be an int.
 +
* Example
 +
 
 +
<syntaxhighlight lang="java5">
 +
 
 +
byte a = 10;
 +
byte b = 20;
 +
byte c = a + b; //WONT work : a+b will be an int
 +
byte c = (byte) a + b; //EXPLICIT cast required
 +
 
 +
</syntaxhighlight>
 +
 
 +
* However as a convenience, compiler automatically inserts a cast when int '''literals''' are assigned to narrower types like byte or short
  
 
<syntaxhighlight lang="java5">
 
<syntaxhighlight lang="java5">
float f = 2; //This is legal. 2 is an int which fits in a float.
+
 
float f = 2.0; //Illegal. 2.0 is a double which by default won't fit in a float.
+
byte c = 10; //Is OK although 10 is an int.
 +
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
* There is no implicit cast for non-literals, however if the variable is marked as final, then the compiler will add the narrowing final cast since the variable is a constant.
 +
 +
<syntaxhighlight lang="java5">
 +
final int i1 = 20;
 +
short s = i1;
 +
 +
int i2 = 20;
 +
short s = i2; //NOT OK, i2 is not final.
 +
 +
</syntaxhighlight>
 +
 +
* '''Watch out!''' the compiler does NOT do the convenience cast for floating point numbers
 +
 +
<syntaxhighlight lang="java5">
 +
 +
float f = 2;  //This is legal. 2 is an int which fits in a float. (Widening)
 +
float f = 2.0; //Illegal. 2.0 is a double which by default won't fit in a float. (Narrowing, but no auto cast by the compiler)
 +
 +
</syntaxhighlight>
 +
 +
 +
* '''IMPORTANT''' : For compound assignment operators involving smaller than int sized operators ( +=, -=, *=, /=) the compiler puts in an implicit cast.
 +
* If the assignment results in a greater value than the type can hold, it will spill over - there wont be any error.
 +
 +
<syntaxhighlight lang="java5">
 +
 +
byte a = 5;
 +
byte b = 10;
 +
 +
byte c = a + b; //WONT WORK AS ABOVE !
 +
 +
a *= b; //OK !
 +
 +
System.out.println(a); //Prints 50;
 +
 +
</syntaxhighlight>
 +
 +
=== Char Int Compatibility ===
 +
 +
* Under the hood a char is a 2-byte unsigned integer
 +
* A char's int value is a code which corresponds to a unicode character.
 +
* A char can be assigned int values without any cast.
 +
* Mathematical operations and incr/decr can be performed on a char.
 +
* The below method prints the entire alphabet. Note char is initialized to 65, the code for 'A'.
 +
 +
<syntaxhighlight lang="java5">
 +
 +
public static void main(String[] args) {
 +
 +
char c = 65;
 +
 +
for(int i=0; i < 26; i++) {
 +
System.out.println(c++);
 +
}
 +
 +
}
 +
 +
 +
</syntaxhighlight>
 +
  
 
[[Category:OCPJP]]
 
[[Category:OCPJP]]

Latest revision as of 01:23, 8 September 2011

  • Default type of an integer literal is int.
  • Long can be specified by adding l or L
  • Octal prefix with 0
  • Hex prefix with 0x or 0X
  • Floating point literals default type is double.
float pi = 3.14; // This will be a compiler error, because 3.14 is a fp literal which is double by default
double pi = 3.14; //OK
float pi = 3.14f; //OK
  • Double can also be explicitly by adding the suffix d or D
  • Float is denoted by suffix f or F
  • Integers are stored in 2 complements's notation
  • Leftmost bit is the sign bit, the remaining bits are used to store the value
  • Consider Byte:
    • Byte - 1 byte = 8 bits.
    • Leftmost bit is to store the sign. So 7 bits are available for the value, so 2^7 = 128 values
    • Negative range is -128 to -1 (128 numbers)
    • Positive range is 0 to 127 (128 numbers, 0 is stored as a positive number)
    • So a byte's range is -2^7 to (2^7 - 1) - A total of 256 numbers;
  • Character's take up 2 bytes
  • they are stored as unsigned 16-bit integers. This means they will represent a total of 2^16 positive values (0 to 65535 (2^16-1) )
  • contrast with short which also uses 2 bytes. But it's max positive range is 2^15 -1. (Since 1 bit is to used to represent the sign)

Assignments

  • A literal integer is always implicitly an int.
  • The compiler will issue an error when it can see that literal value is too large for the variable.
  • This can be fixed by explict casting, however if the value is too large - no runtime error will occur - the value will simply "spill" over.
  • All the higher order bits are truncated - for e.g. int is 32 bits and byte is 8 bits - so top 24 bits will be chopped off.
byte by =  128;	//Compiler error

byte by = (byte) 128; //OK with explicit cast
System.out.println(by); //Prints -128 after spill over.
  • An implicit cast will happen when a widening conversion is being performed.
  • So a byte being assigned to int, or an int assigned to a long is OK
  • An explicit cast is required for narrowing conversions. e.g. float to an int, or a long to an int.
long lon1 = 100;

int int1 = (int) lon1;
  • IMPORTANT : the result of an expression involving anything int-sized or smaller is always an int. e.g. an operation involving two bytes will be an int.
  • Example
byte a = 10;
byte b = 20;
byte c = a + b; //WONT work : a+b will be an int
byte c = (byte) a + b; //EXPLICIT cast required
  • However as a convenience, compiler automatically inserts a cast when int literals are assigned to narrower types like byte or short
byte c = 10; //Is OK although 10 is an int.
  • There is no implicit cast for non-literals, however if the variable is marked as final, then the compiler will add the narrowing final cast since the variable is a constant.
final int i1 = 20;
short s = i1;

int i2 = 20;
short s = i2; //NOT OK, i2 is not final.
  • Watch out! the compiler does NOT do the convenience cast for floating point numbers
float f = 2;  //This is legal. 2 is an int which fits in a float. (Widening)
float f = 2.0; //Illegal. 2.0 is a double which by default won't fit in a float. (Narrowing, but no auto cast by the compiler)


  • IMPORTANT : For compound assignment operators involving smaller than int sized operators ( +=, -=, *=, /=) the compiler puts in an implicit cast.
  • If the assignment results in a greater value than the type can hold, it will spill over - there wont be any error.
byte a = 5;
byte b = 10;

byte c = a + b; //WONT WORK AS ABOVE !
		
a *= b; //OK ! 
		
System.out.println(a); //Prints 50;

Char Int Compatibility

  • Under the hood a char is a 2-byte unsigned integer
  • A char's int value is a code which corresponds to a unicode character.
  • A char can be assigned int values without any cast.
  • Mathematical operations and incr/decr can be performed on a char.
  • The below method prints the entire alphabet. Note char is initialized to 65, the code for 'A'.
public static void main(String[] args) {
		
		char c = 65;
		
		for(int i=0; i < 26; i++) {
			System.out.println(c++);
		}

}