COMP1521 24T1 — Integers
https://www.cse.unsw.edu.au/~cs1521/24T1/
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 1 / 25
10 types of students
There are only 10 types of students …
• those that understand binary
• those that don’t understand binary
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 2 / 25
Decimal Representation
• Can interpret decimal number 4705 as:
4 × 103 + 7 × 102 + 0 × 101 + 5 × 100
• The base or radix is 10 … digits 0 – 9
• Place values:
… 1000 100 10 1
3 2 1
… 10 10 10 100
• Write number as 470510
• Note use of subscript to denote base
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 3 / 25
Representation in Other Bases
• base 10 is an arbitrary choice
• can use any base
• e.g. could use base 7
• Place values:
… 343 49 7 1
… 73 72 71 70
• Write number as 12167 and interpret as:
1 × 73 + 2 × 72 + 1 × 71 + 6 × 70 == 45410
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 4 / 25
Binary Representation
• Modern computing uses binary numbers
• because digital devices can easily produce high or low level voltages which can represent 1 or 0.
• The base or radix is 2
Digits 0 and 1
• Place values:
⋯ 8 4 2 1
⋯ 23 22 21 20
• Write number as 10112 and interpret as:
1 × 23 + 0 × 22 + 1 × 21 + 1 × 20 == 1110
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 5 / 25
Converting between Binary and Decimal
• Example: Convert 11012 to Decimal:
• Example: Convert 29 to Binary:
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 6 / 25
Hexadecimal Representation
• Binary numbers hard for humans to read — too many digits!
• Conversion to decimal awkward and hides bit values
• Solution: write numbers in hexadecimal!
• The base or radix is 16 … digits 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
• Place values:
… 4096 256 16 1
… 163 162 161 160
• Write number as 3𝐴𝐹 116 and interpret as:
3 × 163 + 10 × 162 + 15 × 161 + 1 × 160 == 1508910
• in C, 0x prefix denotes hexadecimal, e.g. 0x3AF1
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 7 / 25
Octal & Binary C constants
• Octal (based 8) representation used to be popular for binary numbers
• Similar advantages to hexadecimal
• in C a leading 0 denotes octal, e.g. 07563
• binary constants were only recently added to C - some C compilers will not recognize them
printf("%d", 0x2A); // prints 42
printf("%d", 052); // prints 42
printf("%d", 0b101010); // might compile and print 42
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 8 / 25
Binary Constants
In hexadecimal, each digit represents 4 bits
0100 1000 1111 1010 1011 1100 1001 0111
0x 4 8 F A B C 9 7
In octal, each digit represents 3 bits
01 001 000 111 110 101 011 110 010 010 111
0 1 1 0 7 6 5 3 6 2 2 7
In binary, each digit represents 1 bit
0b01001000111110101011110010010111
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 9 / 25
Binary to Hexadecimal
• Example: Convert 10111110001010012 to Hex:
• Example: Convert 101111010111002 to Hex:
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 10 / 25
Hexadecimal to Binary
• Reverse the previous process …
• Convert each hex digit into equivalent 4-bit binary representation
• Example: Convert 𝐴𝐷516 to Binary:
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 11 / 25
Unsigned integers
The unsigned int data type
• on cse machines is 32 bits, storing values in the range 0 .. 232 -1
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 12 / 25
Signed integers
The int data type
• on cse machines is 32 bits, storing values in the range -231 .. 231 -1
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 13 / 25
Representing Negative Integers
• modern computers almost always use two’s complement to represent integers
• positive integers and zero represented in obvious way
• negative integers represented in clever way to make arithmetic in silicon fast/simpler
• for an n-bit binary number the representation of −𝑏 is 2𝑛 −𝑏
• e.g. in 8-bit two’s complement −5 is represented as 28 − 5 == 111110112
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 14 / 25
Code example: printing all 8 bit twos complement bit patterns
• Some simple code to examine all 8 bit twos complement bit patterns.
for (int i = -128; i < 128; i++) {
printf("%4d ", i);
print_bits(i, 8);
printf("\n");
}
source code for 8_bit_twos_complement.c
$ dcc 8_bit_twos_complement.c print_bits.c -o 8_bit_twos_complement
source code for print_bits.c source code for print_bits.h
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 15 / 25
Code example: printing all 8 bit twos complement bit patterns
$ ./8_bit_twos_complement
-128 10000000
-127 10000001
-126 10000010
...
-3 11111101
-2 11111110
-1 11111111
0 00000000
1 00000001
2 00000010
3 00000011
...
125 01111101
126 01111110
127 01111111
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 16 / 25
Code example: printing bits of int
int a = 0;
printf("Enter an int: ");
scanf("%d", &a);
// sizeof returns number of bytes, a byte has 8 bits
int n_bits = 8 * sizeof a;
print_bits(a, n_bits);
printf("\n");
source code for print_bits_of_int.c
$ dcc print_bits_of_int.c print_bits.c -o print_bits_of_int
$ ./print_bits_of_int
Enter an int: 42
00000000000000000000000000101010
$ ./print_bits_of_int
Enter an int: -42
11111111111111111111111111010110
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 17 / 25
Code example: printing bits of int
$ ./print_bits_of_int
Enter an int: 0
00000000000000000000000000000000
$ ./print_bits_of_int
Enter an int: 1
00000000000000000000000000000001
$ ./print_bits_of_int
Enter an int: -1
11111111111111111111111111111111
$ ./print_bits_of_int
Enter an int: 2147483647
01111111111111111111111111111111
$ ./print_bits_of_int
Enter an int: -2147483648
10000000000000000000000000000000
$
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 18 / 25
Bits in Bytes in Words
• Many hardware operations works with bytes: 1 byte == 8 bits
• C’s sizeof gives you number of bytes used for variable or type
• sizeof variable - returns number of bytes to store variable
• sizeof (type) - returns number of bytes to store type
• On CSE servers, C types have these sizes
• char = 1 byte = 8 bits, 42 is 00101010
• short = 2 bytes = 16 bits, 42 is 0000000000101010
• int = 4 bytes = 32 bits, 42 is 00000000000000000000000000101010
• double = 8 bytes = 64 bits, 42 = ?
• above are common sizes but not universal on a small embedded CPU
sizeof (int) might be 2 (bytes)
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 19 / 25
Code example: integer_types.c - exploring integer types
We can use sizeof and limits.h to explore the range of values
which can be represented by standard C integer types on our machine…
$ dcc integer_types.c -o integer_types
$ ./integer_types
Type Bytes Bits
char 1 8
signed char 1 8
unsigned char 1 8
short 2 16
unsigned short 2 16
int 4 32
unsigned int 4 32
long 8 64
unsigned long 8 64
long long 8 64
unsigned long long 8 64
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 20 / 25
Code example: integer_types.c - exploring integer types
Type Min Max
char -128 127
signed char -128 127
unsigned char 0 255
short -32768 32767
unsigned short 0 65535
int -2147483648 2147483647
unsigned int 0 4294967295
long -9223372036854775808 9223372036854775807
unsigned long 0 18446744073709551615
long long -9223372036854775808 9223372036854775807
unsigned long long 0 18446744073709551615
source code for integer_types.c
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 21 / 25
stdint.h - integer types with guaranteed sizes
#include <stdint.h>
• to get below integer types (and more) with guaranteed sizes
• we will use these heavily in COMP1521
// range of values for type
// minimum maximum
int8_t i1; // -128 127
uint8_t i2; // 0 255
int16_t i3; // -32768 32767
uint16_t i4; // 0 65535
int32_t i5; // -2147483648 2147483647
uint32_t i6; // 0 4294967295
int64_t i7; // -9223372036854775808 9223372036854775807
uint64_t i8; // 0 18446744073709551615
source code for stdint.c
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 22 / 25
Code example: char_bug.c
Common C bug:
char c; // c should be declared int (int16_t would work, int is better)
while ((c = getchar()) != EOF) {
putchar(c);
}
Typically stdio.h contains:
#define EOF -1
• most platforms: char is signed (-128..127)
• loop will incorrectly exit for a byte containing 0xFF
• rare platforms: char is unsigned (0..255)
• loop will never exit
source code for char_bug.c
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 23 / 25
Endian-ness
• The bytes of a multi-byte (2 byte, 4 byte, …) quantity can be stored in various orders.
• Endian-ness is the order.
• Two common orders: big-endian & little-endian
• big-endian - most significant byte at the smallest memory address.
• little-endian - least significant byte at the smallest memory address.
• Most modern general-purpose computers little-endian
• Endian-ness configurable on some architectures e.g ARM
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 24 / 25
Testing Endian-ness
C MIPS
uint8_t b; lbu $a0, u # b = *(uint8_t *)&u;
uint32_t u; li $v0, 1 # printf("%d", a0);
u = 0x03040506; syscall
// load first byte of u li $a0, '\n' # printf("%c", '\n');
b = *(uint8_t *)&u; li $v0, 11
// prints 6 if little-endian syscall
// and 3 if big-endian li $v0, 0 # return 0
printf("%d\n", b); jr $ra
source code for endian.c
.data
u:
.word 0x3040506 #u = 0x03040506;
source code for endian.s
https://www.cse.unsw.edu.au/~cs1521/24T1/ COMP1521 24T1 — Integers 25 / 25