(Related reading in text: pp. 177--181)
Just as with decimal numbers:
Numbers are stored so as to:
The two's complement of an n-bit integer value i is:
The unary complement operator inverts (or ``flips'') all the bits in a
number:
If i and j are integer values, then
i & j (the ``bitwise-and'' of i and j) means:
For example:
Q: What's an easy way to check if a number is even?
A: Check the least-significant bit (one's place) in the binary
representation:
Goal: Given an integer value i, display its underlying binary
representation.
Idea: Do not treat i as if it were represented in base
10. Instead, make use of the bitwise operations.
To identify the binary representation of a value of Java's byte> type:
Suppose we want to know if the 32-place bit is set in the number 91:
Observe:
22 00010110
44 00101100
n << k means shift n (in binary) to the left
k bits and
add k zeros on the right. The left-most k bits are
discarded.
n >> k means shift n (in binary) to the right
k bits and add k zeros on the left (if n > 0) or
k ones on the left (if n < 0). The right-most
k bits are discarded.
Click here to try an applet that
demonstrates the effects of the shift operations.
Click here to see the Java code for the
applet.
Examine the code below, used to display a number as a binary
string. Notice how redundant the body of the method
toBinaryString is. There has got to be a better way... there
is! Tune in next week for more info.
Binary Numbers
Just a Bunch of Zeros and Ones
Some Powers of Two
power of 2 base-10 base-2 (binary)
--------------------------------------------
20 1 1
21 2 10
22 4 100
23 8 1000
24 16 10000
25 32 100000
26 64 1000000
27 128 10000000
28 256 100000000
29 512 1000000000
210 1024 10000000000
211 2048 100000000000
212 4096 1000000000000
...
Binary-Number Examples
23 = 16 + 0 + 4 + 2 + 1
1 0 1 1 1 = 10111
252 = 128 + 64 + 32 + 16 + 8 + 4 + 0 + 0
1 1 1 1 1 1 0 0
= 11111100
5017 = 4096 + 0 + 0 + 512 + 256 +
128 + 0 + 0 + 16 + 8 + 0 + 0 + 1
= 1001110011001
Addition of Binary Numbers
23 10111
+37 100101
--------------------
60 111100 = 32 + 16 + 8 + 4
Lingo
Review: Integer Values in Java
-9,223,372,036,854,775,808 ...
9,223,372,036,854,775,807
Two's Complement
The Other Side
In order to meet these needs, integer values
(byte, short, int, long are stored using
two's complement representation.
For example, assuming byte-sized numbers:
23 ==> 00010111
-23 ==> 11101000 + 1 ===> 11101001
127 ==> 01111111
-127 ==> 10000000 + 1 ===> 10000001
-0 ==> 11111111 + 1 ===> 00000000
-2 ==> 11111101 + 1 ===> 11111110
-1 ==> 11111110 + 1 ===> 11111111
0 ==> 00000000
1 ==> 00000001
2 ==> 00000010
Bitwise Operators
Unary Complement Operator
17 ==> 00010001
~17 ==> 11101110
-17 ==> 11101111
~(-17) ==> 00010000
Bitwise And, Or, Xor Operators
Similarly for | (``bitwise-or''), ^ (``bitwise-xor'').
23 & 37 00010111
00100101
----------------------
5 00000101
23 | 37 00010111
00100101
----------------------
55 00110111
23 ^ 37 00010111
00100101
----------------------
50 00110010
-123 & 1 11101001
00000001
----------------------
00000001
Parity Check
Parity Examples
decimal rep binary rep odd/even
---------------------------------------
5 00000101 ODD
-5 11111011 ODD
100 01100100 EVEN
117 01110101 ODD
22 00010110 EVEN
Parity-Check Method
23 & 1 00010111
00000001
----------------------
00000001 ==> 1
boolean isEven(int i) {
return ((i & 1) == 0);
}
Shift Operators
Uncovering the Binary Representation
An Algorithm (for byte values)
Example: finding the 32-place bit (or any bit)
91 & 32 01011011
00100000
----------------------
00000000 ==> 0
Finding the 2k's-place bit
``Powerful'' Bit Operations
11 00001011
If we ``shift'' the bits one place to the left, and add a 0 at the last
place, we double the number.
The Shift-Left Operator (<<)
11 << 2 00001011
44 00101100
1 << 5 00000001
32 00100000
Shifting left by k multiplies the number by 2k$ (modulo
2m-1 where m is the total number of bits in the
representation.)
The Shift-Right Operator ()
22 >> 2 00010110
5 00000101
-100 >> 3 10011100
-13 11110011
Shifting right by k divides the number by 2k (and rounds
down).
// checks if kth bit in (32-bit) binary representation of
// integer n is on (i.e., 1)
public boolean isKthBitOn(int n, int k) {
if (k < 1)
return false;
else {
int i = n & (1 << (k-1));
return (i != 0);
}
}
// convert kth bit in (32-bit) binary representation of
// integer n to string ("0" or "1")
public String kthBit(int i, int k) {
if (isKthBitOn(i, k))
return "1";
else
return "0";
}
// convert integer i to a String revealing its
// (32-bit) binary representation
public String toBinaryString(int i) {
String s = "";
int k = 1;
// bits 1-8
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
// bits 9-16
s = " " + s;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
// bits 17-24
s = " " + s;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
// bits 25-32
s = " " + s;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
k = k + 1;
s = kthBit(i,k) + s;
return s;
}
}