CPSC 355: Tutorial 5
Binary and Other Representations
PhD Student
Fall 2017
Outline
- The computers we use are binary by design
- 0 is a low voltage (around 0v), and 1is a high voltage (for TTL logic, this is around 3.3v)
- All numbers are represented in binary within a computer
Unsigned Integers
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
Unsigned Integers
In general, for an n-bit number, we have the binary number
equivalent to the decimal number
Octal numbers
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.
Hexadecimal numbers
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.
Representations in C
#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);
}
Bitwise Operations
There are a couple of very useful operations on binary numbers
- Binary OR, | short hand
- Binary AND, & short hand
- Binary NOT, ~ short hand
- Binary XOR, ^ short hand
- Binary Shift Left and Right
These are useful building blocks for arithmetic operations
Bitwise OR
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
Bitwise OR
#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
Bitwise AND
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
Bitwise AND
#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
Bitwise NOT
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
Bitwise NOT
#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
Bitwise XOR
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"
Bitwise XOR
#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
Bitwise Shifts
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
Bitwise Shifts
#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
Bitwise Shifts
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"
Bitwise Shifts
#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 |
Signed Integers
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
Signed Integers
If the sign bit is set, take the 1's complement of the number
Then add 1
The result is then
Signed Integers
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 |
Next Day
Thanksgiving!
CPSC 355: Tutorial 5
By Joshua Horacsek
CPSC 355: Tutorial 5
- 1,604