Reconfigurable computing
Small Embedded Systems
Unit 2.1: Data Representation and Data Types
Introduction
Binary and hexadecimal
Signed and unsigned
Types in the C language
First question:
Why do we care about how numbers are represented?
European Space Agency Ariane 5
First launch of Ariane 5 series (1996)
Self destructed 39 seconds after launch because veering dangerously off course
Cost ~€150 million
Guidance system produced lateral velocity as 64-bit floating point number
Converted into 16-bit integer value
Caused overflow because value too big
Not protected because designers assumed number could never get that big
By DLR German Aerospace Center – Raumfrachter ATV-4 “Albert Einstein” Ariane 5ES Rollout_4, CC BY 2.0, https://commons.wikimedia.org/w/index.php?curid=26533952
Software had been copied from Ariane 4 (different hardware system, which met the designers’ assumptions) without modification
Binary and Hexadecimal
Representation in the C language
Hexadecimal literal values are indicated by prefix 0x
Modern standard also says that prefix of 0b can be used for binary literals
N.B. Some older C compilers don’t implement the 0b feature
myVariable = 0x3F
myVariable = 0b00111111
Unsigned binary
Each digit can be a 1 or a 0
Digit i is a multiple of 2i
Example:
Convert binary 0b11000100 to its denary equivalent
Answer = 1×128 + 1×64 + 1×4 = 196
This can only represent positive numbers
An n-bit number can represent 2n different values
8-bits can represent numbers in the range 0 to 255.
Power of 2 (2n) 27 26 25 24 23 22 21 20
Power of 2 128 64 32 16 8 4 2 1
Digit of our number 1 1 0 0 0 1 0 0
Binary Numbers Terminology
Each digit in a binary number is known as a “bit”.
A group of eight bits is called a “byte”
A group of bits that we use to represent our data items is known as a “word”.
Typical word lengths are 8, 12, 16, 32, 64
6
Signed and Unsigned
The type of binary that we have just seen can only represent positive numbers
Some quantities can only be positive, so this is a good representation
Other quantities can be positive or negative, so we need an alternative representation
Standard signed representation is 2s complement
Counting with a Fixed Number of Digits
Cars have odometers
Count number of miles (or km) driven
Older cars had only 5 digit odometers:
After 99,999 miles
Drive 1 mile further and odometer says 00,000
If you were buying a 2nd hand car and odometer said 20,000
That could be a true reading,
or it could be 120,000 miles
Image from http://www.corvetteblog.com/2015/02/what-does-exempt-mileage-mean/
Negative Numbers: 2s Complement
Basic idea:
8-bit counter follows sequence
00000000
00000001
11111100
11111101
11111110
11111111
00000000
…
-1 means the number that gives zero when we add one to it
This is the number that gives zero when we add one
Use this to represent -1
…
Negative Numbers: 2s Complement
Basic idea:
8-bit counter follows sequence
00000000
00000001
11111100
11111101
11111110
11111111
00000000
…
This is the number that gives zero when we add two
Use this to represent -2
…
Signed binary (2s Complement)
The most significant bit has negative weight
Example:
Convert binary 0b11111110 to its denary equivalent
1×-128 + 1×64 + 1×32 + 1×16 + 1×8 + 1×4 + 1×2 = -2
Power of 2 (2n) -27 26 25 24 23 22 21 20
Power of 2 -128 64 32 16 8 4 2 1
Digit of our number 1 1 1 1 1 1 1 0
Signed binary (2s Complement)
The most significant bit has negative weight
Another example:
Convert binary 0b11000100 to its denary equivalent
Answer = 1×-128 + 1×64 + 1×4 = -60
Can represent both positive and negative numbers
An n-bit number can represent 2n different values
8-bits can represent numbers in range -128 to +127
Power of 2 (2n) -27 26 25 24 23 22 21 20
Power of 2 -128 64 32 16 8 4 2 1
Digit of our number 1 1 0 0 0 1 0 0
Hexadecimal
Another important number system is base 16 (hexadecimal)
The hexadecimal digital are:
Hex digit Meaning (base 10) Binary
0 0 0000
1 1 0001
2 2 0010
3 3 0011
4 4 0100
5 5 0101
6 6 0110
7 7 0111
8 8 1000
9 9 1001
A 10 1010
B 11 1011
C 12 1100
D 13 1101
E 14 1110
F 15 1111
13
Binary to Hex / Hex to Binary
Each group of four binary bits maps on to a single hex digit:
0b01101001 = 0x69
Hexadecimal can be used as a kind of “shorthand” for binary numbers
0x69 = 6 × 161 + 9 × 160
= 6 × 16 + 9 × 1
= 105 in base 10
0110 1001
6 9
14
Another Hex Example
Convert 0x2D3 to binary
Hex Denary Binary
0 0 0000
1 1 0001
2 2 0010
3 3 0011
4 4 0100
5 5 0101
6 6 0110
7 7 0111
8 8 1000
9 9 1001
A 10 1010
B 11 1011
C 12 1100
D 13 1101
E 14 1110
F 15 1111
Hex Denary
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
A 10
B 11
C 12
D 13
E 14
F 15
001011010011
0010
1101
0011
15
Data Types in C
The C language standard has several types of int:
short int
int
long int
The standard does not say what size they must be
They are allowed to be different between different processors, but the following must be true:
short int must be at least 16 bit (2 bytes)
sizeof(int) >= sizeof(short int)
sizeof(long int) >= sizeof(int)
Data Types in C
This code will tell us the size of C variables on our microcontroller:
short int i;
int j;
long int k;
void setup() {
Serial.begin(9600);
Serial.print(“short int=”);
Serial.print(sizeof(i));
Serial.print(” bytes \t int=”);
Serial.print(sizeof(j));
Serial.print(” bytes \t long int=”);
Serial.print(sizeof(k));
Serial.println(” bytes”);
}
void loop () {}
Setup function runs at start
Start communication to host PC
Some variables are declared
Print the size (in bytes)
Data Types in C
That’s quite typical
This 8-bit processor uses 16 bits for type int
This 32-bit processor uses 32 bits for type int
Usually this doesn’t matter much
8-bit processors handle 16-bit or 32-bit items by using successive data memory locations to store the bytes
32-bit processors can handle 16-bit data by zero-padding the machine word
Output from Uno with ATmega 328P
Output from Feather Huzzah with ESP8266
Overflow for Unsigned Numbers
However, it matters if we are counting up to big numbers
Unsigned range:
16-bit 0 to 65,535
32-bit 0 to 4,294,967,295
16-bit millisecond timer will overflow and reset to zero after 1.1 minutes
Output from Uno with ATmega 328P
Output from Feather Huzzah with ESP8266
Overflow for Signed Numbers
Signed range:
16-bit -32,768 to 32,767
Counts up to 0111111111111111 (decimal 32,767)
The becomes negative at next count:
1000000000000000 (decimal -32,768)
This can fool comparisons (e.g. on loop bounds)
while (i<1000) {
// Loop body goes here
}
If i has become very big and overflowed, its value is now negative
This comparison evaluates to true and the loop executes when it shouldn’t
The Brief Conclusion
If you are using a variable to represent a timer, think carefully about the maximum count value.
If in doubt declare it as long int
Taking Control of Bitwidth
The variability of sizeof(int), especially with embedded systems, can cause problems of portability
C99 standard introduces types with explicit size:
int8_t 8-bit signed integer
uint8_t 8-bit unsigned integer
int16_t 16-bit signed integer
uint16_t 16-bit unsigned integer
int32_t 32-bit signed integer
uint32_t 32-bit unsigned integer
Definitions held in
Taking Control
Here is a code example:
N.B
uint8_t i;
uint16_t j;
uint32_t k;
void setup() {
Serial.begin(9600);
Serial.print(sizeof(i));
Serial.print(sizeof(j));
Serial.println(sizeof(k));
}
void loop () {}
Declare some variables with explicit bitwidth
Connect to host PC
Prints 1
Prints 2
Prints 4
Summary
Size of int is not defined in standard and varies between different processors
We can declare with exact size (e.g. uint8_t) to make our code more portable
Care must be taken to avoid overflow of short int values, especially in counter circuits
/docProps/thumbnail.jpeg