# Lesson 1

# Functions and Programs

A function is a relation that uniquely associates members of one set with members of another

- Wolfram 2019

ie. a function transforms some input into some output.

A program is essentially a function, or a collection of functions that perform some task.

For a function say f(x) = x^2, this transforms the input x, into the output, by performing the operation x^2 on it.

A program takes particualr inputs (files, user interaction, network etc.) and by performing operations (the code itself) performs some sort of output (display, print, network etc.).

# Bits and Bytes

Just like in math where you have particular numerical domains where you operate within (real, intergers, imaginary etc.), computers operate within particular finite domains.

To store data in computers, you store them as 1’s and 0’s. (see: transistors)

A single 0/1 digit is known as a bit.

A collection of 8 of these is known as a byte. (4 bits is a nibble, but don’t worry about that)

Note: that with a single bit, you can have 2 states: (0, 1).

With 2 bits you can have 4 states: (00, 01, 10, 00).

With 3 bits you have 8, 4 you have 16 etc.

The number of states you can have with n bits, is 2^n.

bits bytes states
8 1 256
16 2 65536
32 4 4294967296
64 8 18446744073709551616

If we want to store non-negative intgers (including 0), then we can store 0, up to one less then the number of states. This is because 0 takes up one of these states.

What if you want to store negative intgers?

We can use one of these states, to store essentially a negative sign (see: two’s complement).

Ex: 1 byte would have the range of -128 -> 127.

However these only store integer values (as those have specified distances between numbers (1)).

# Binary Representation

Decimal is base 10, which is what we’re all used to working with.

Computers operate in base 2 (0/1).

To convert from binary, multiply each digit by the corresponding power of 2.

Ex: 0b10010011 (we’ll be using the 0b prefix, to denote binary values).

Where the right most digit is the lowest magnitude (see: endianness), ie 2^0 = 1

So:

(1 * 2^0) + (1 * 2^1) + (0 * 2^2) + (0 * 2^3) + (1 * 2^4) + (0 * 2^5) + (0 * 2^6) + (1 * 2^7)
= 1 + 2 + 0 + 0 + 16 + 0 + 0 + 128
= 147

To convert to binary, simply split the decimal value into powers of 2.

Ex:

4189 = 2^12 + 2^6 + 2^4 + 2^3 + 2^2 + 2^0

So: as binary this is 0b1000001011101

# and… Hexadecimal

0b10011011 0b1011111011110111

Binary, lots of binary. Really annoying do deal with.

What if there was a way to represent numbers in a way that computers can still internally deal with them as binary, but we can deal with them in a nice and orderly fashion?

Consider base 16.

0x0-0xF represents the values 0-15. (we’ll be using the 0x prefix, to denote hexadecimal (hex) values).

0b10011011 = 0x9b

0b1011111011110111 = 0xbef7

We can convert between hex and decimal, just like we convert between binary and decimal.

ex:

0x9b = (9 * 16^1) + (11 * 16^0) = 155

0xbef7 = (11 * 16^3) + (14 * 16^2) + (15 * 16^1) + (7 * 16^0) = 48887

We can also convert between binary and hex we note:

0b 0x
0000 0
0001 1
0010 2
0011 3
0100 4
1000 8
1001 9
1010 A
1011 B
1110 E
1111 F

Fill in the rest as an exercise :p

So: given 0b1000001011101 we can convert easily to hex:

0b 0001 0000 0101 1101 = 0x105D

What about decimals?

# Decimals

To represent decimals in computers, there are multiple ways.

Fixed point, where we specify that the first x bytes represent the number before the decimal, and the last y, represent the number after the decimal. ie. two integers, stick a decimal in between.

This is good for when we need fixed precision, ie. say we have money the dollar value could be an 8 byte integer, whereas the cents might be a 1 byte integer (cause it only needs to go up to 0-99)

The other method is called floating point. where we store a decimal value of essentially 1.x * 2^y.

Where x and y are some integers. (see: IEEE Standard 754)

# Conclusion

You should now be able to see, how we can store various kinds of numerical data, in simply bits.