Binary and Other Representations
PhD Student
Fall 2017
Binary | Decimal |
---|---|
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
1000 | 8 |
1001 | 9 |
1010 | 10 |
1011 | 11 |
1100 | 12 |
1101 | 13 |
1110 | 14 |
1111 | 15 |
Consider a bit number, the representation we choose is a base 2 representation, that is, if we have some binary number
Then the decimal representation is
For example
In general, for an n-bit number, we have the binary number
equivalent to the decimal number
Binary | Octal | Decimal |
---|---|---|
0000 | 0 | 0 |
0001 | 1 | 1 |
0010 | 2 | 2 |
0011 | 3 | 3 |
0100 | 4 | 4 |
0101 | 5 | 5 |
0110 | 6 | 6 |
0111 | 7 | 7 |
1000 | 10 | 8 |
Octal representation, or a base 8 representation, is similar, but with each digit taking a value between 0-7.
One octal digit is a group of 3 bits.
Binary | Octal | Decimal | Hexadecimal |
---|---|---|---|
0000 | 0 | 0 | 0 |
0001 | 1 | 1 | 1 |
0010 | 2 | 2 | 2 |
0011 | 3 | 3 | 3 |
0100 | 4 | 4 | 4 |
0101 | 5 | 5 | 5 |
0110 | 6 | 6 | 6 |
0111 | 7 | 7 | 7 |
1000 | 10 | 8 | 8 |
1001 | 11 | 9 | 9 |
1010 | 12 | 10 | A |
1011 | 13 | 11 | B |
1100 | 14 | 12 | C |
1101 | 15 | 13 | D |
1110 | 16 | 14 | E |
1111 | 17 | 15 | F |
Hexadecimal representation, or a base 16 representation, is similar, but with each digit taking a value between 0-F.
One hexadecimal digit is a group of 4 bits.
#include <stdio.h> // Include functions from the standard I/O library
int main(int argc, char *argv[])
{
// "Literals" are a sort of way of writing values in a different way
int v3 = 0xFEEDDAD; // Is a hexadecimal literal
int v4 = 0b10010011; // Is a binary literal (but this is not standard C!)
int v5 = 022222222; // an octal literal (notice the first 0).
printf("v3 = %d, 0x%x, 0%o\n", v3, v3, v3);
printf("v4 = %d, 0x%x, 0%o\n", v4, v4, v4);
printf("v5 = %d, 0x%x, 0%o\n", v5, v5, v5);
}
There are a couple of very useful operations on binary numbers
These are useful building blocks for arithmetic operations
An OR between two bits a, and b, truth table
a\b | 0 | 1 |
---|---|---|
0 | 0 | 1 |
1 | 1 | 1 |
1001
OR 0101
--------
1101
Example
Think of this as "forcing bits to be set" in a register
#include <stdio.h>
void main(int argc, char *argv[]) {
char a = 0b1001;
char b = 0b0111;
printf("a=0x%x, b=0x%x\na|b = 0x%x\n", a, b, a|b);
}
fmt: .string "a=0x%x, b=0x%x\na|b = 0x%x\n"
.balign 4
.global main
main:
stp x29, x30, [sp, -16]!
mov x29, sp
ldr x0, =fmt
mov x1, 0b1001
mov x2, 0b0111
orr x3, x2, x1
bl printf
ldp x29, x30, [sp], 16
ret
An AND between two bits a, and b, truth table
a\b | 0 | 1 |
---|---|---|
0 | 0 | 0 |
1 | 0 | 1 |
1001
AND 0101
--------
0001
Example
Think of this as "masking out" bits
#include <stdio.h>
void main(int argc, char *argv[]) {
char a = 0b1001;
char b = 0b0111;
printf("a=0x%x, b=0x%x\na&b = 0x%x\n", a, b, a&b);
}
fmt: .string "a=0x%x, b=0x%x\na&b = 0x%x\n"
.balign 4
.global main
main:
stp x29, x30, [sp, -16]!
mov x29, sp
ldr x0, =fmt
mov x1, 0b1001
mov x2, 0b0111
and x3, x2, x1
bl printf
ldp x29, x30, [sp], 16
ret
An AND between two bits a, and b, truth table
a | 0 | 1 |
---|---|---|
~a | 1 | 0 |
NOT 1001
--------
0110
Example
Think of this as "flipping" bits
#include <stdio.h>
void main(int argc, char *argv[]) {
char a = 0b1001;
printf("a=0x%x, ~a=0x%x\n", a, ~a);
}
fmt: .string "a=0x%x, ~a=0x%x\n"
.balign 4
.global main
main:
stp x29, x30, [sp, -16]!
mov x29, sp
ldr x0, =fmt
mov x1, 0b1001
mvn x2, x1 // Move and NOT
bl printf
ldp x29, x30, [sp], 16
ret
An eXclusive OR between two bits a, and b, truth table
a\b | 0 | 1 |
---|---|---|
0 | 0 | 1 |
1 | 1 | 0 |
1001
XOR 0101
--------
1100
Example
Think of this as "a bitwise toggle"
#include <stdio.h>
void main(int argc, char *argv[]) {
char a = 0b1001;
char b = 0b0111;
printf("a=0x%x, b=0x%x\na&b = 0x%x\n", a, b, a^b);
}
fmt: .string "a=0x%x, b=0x%x\na&b = 0x%x\n"
.balign 4
.global main
main:
stp x29, x30, [sp, -16]!
mov x29, sp
ldr x0, =fmt
mov x1, 0b1001
mov x2, 0b0111
eor x3, x2, x1
bl printf
ldp x29, x30, [sp], 16
ret
It's also often useful to shift bits left and right in a register, for this we have >> (shift right) and << (shift left). Bits that exceed the width of the register are dropped
1001 >> 1
--------
0100
Example
Shift left can be used as a fast "multiply by 2" and shift right can be used as a fast "integer divide by 2"
1001 << 1
--------
0010
#include <stdio.h>
void main(int argc, char *argv[]) {
unsigned int a = 0b1100;
unsigned int b = 0b1001;
printf("a=%d, b=%d\na >> 2 = %d, b << 2 = %d\n", a, b, a >> 2, b << 2);
}
fmt: .string "a=%d, b=%d\na >> 2 = %d, b << 2 = %d\n"
.balign 4
.global main
main:
stp x29, x30, [sp, -16]!
mov x29, sp
ldr x0, =fmt
mov x1, 0b1100
mov x2, 0b1001
lsr x3, x1, 2
lsl x4, x2, 2
bl printf
ldp x29, x30, [sp], 16
ret
For signed quantities, it is often important to keep the sign bit, this is what an arithmetic shift does
1001 >> 1
--------
1100
Example
Shift left can be used as a fast "multiply by 2" and shift right can be used as a fast "integer divide by 2"
#include <stdio.h>
void main(int argc, char *argv[]) {
unsigned int a = -1; //0b1111...111 in binary
unsigned int b = -1; //
printf("a=%d, b=%d\na >> 1 = %d, b << 1 = %d\n", a, b, a >> 1, b << 1);
}
fmt: .string "a=%d, b=%d\na >> 2 = %d, b << 2 = %d\n"
.balign 4
.global main
main:
stp x29, x30, [sp, -16]!
mov x29, sp
ldr x0, =fmt
mov w1, -1
mov w2, -1
asr w3, w1, 1
lsl w4, w2, 1 // LSL is an Arithmetic shift
bl printf
ldp x29, x30, [sp], 16
ret
Binary | Octal | Decimal | Hex |
---|---|---|---|
0000 | 0 | 0 | 0 |
0001 | 1 | 1 | 1 |
0010 | 2 | 2 | 2 |
0011 | 3 | 3 | 3 |
0100 | 4 | 4 | 4 |
0101 | 5 | 5 | 5 |
0110 | 6 | 6 | 6 |
0111 | 7 | 7 | 7 |
1000 | 10 | 8 | 8 |
1001 | 11 | 9 | 9 |
1010 | 12 | 10 | A |
1011 | 13 | 11 | B |
1100 | 14 | 12 | C |
1101 | 15 | 13 | D |
1110 | 16 | 14 | E |
1111 | 17 | 15 | F |
Treat the highest bit as the 'sign' bit. If it's 1, then the signed integer is negative.
Sign bit
If the sign bit isn't set, then we're done, and the value of the integer is the same as the unsigned integer
If the sign bit is set, take the 1's complement of the number
Then add 1
The result is then
Binary | Octal | Hexadecimal | Signed Decimal |
---|---|---|---|
0000 | 0 | 0 | 0 |
0001 | 1 | 1 | 1 |
0010 | 2 | 2 | 2 |
0011 | 3 | 3 | 3 |
0100 | 4 | 4 | 4 |
0101 | 5 | 5 | 5 |
0110 | 6 | 6 | 6 |
0111 | 7 | 7 | 7 |
1000 | 10 | 8 | -8 |
1001 | 11 | 9 | -7 |
1010 | 12 | A | -6 |
1011 | 13 | B | -5 |
1100 | 14 | C | -4 |
1101 | 15 | D | -3 |
1110 | 16 | E | -2 |
1111 | 17 | F | -1 |
Thanksgiving!