Single number can be written using different notations, each of them representing that a number differently.

**Decimal Notation.**

in decimal system we use 10 digits: from 0 to 9, we base them on consecutively following powers of ten.

for example, number 1984 we can write as:

1984d = 1 * 10

^{3}+ 9 * 10

^{2}+ 8 * 10

^{1}+ 4 * 10

^{0}.

number 1984.75 we can write as:

1984.75d = 1 * 10

^{3}+ 9 * 10

^{2}+ 8 * 10

^{1}+ 4 * 10

^{0}+ 7 * 10

^{-1}+ 5 * 10

^{-2}.

**Binary Notation.**

similarly, in decimal system we use two digits: from 0 to 1, we base them on consecutively following powers of two.

11111000000b = 1 * 2

^{10}+ 1 * 2

^{9}+ 1 * 2

^{8}+ 1 * 2

^{7}+ 1 * 2

^{6}+ 0 * 2

^{5}+ 0 * 2

^{4}+ 0 * 2

^{3}+ 0 * 2

^{2}+ 0 * 2

^{1}+ 0 * 2

^{0}= 1024 + 512 + 256 + 128 + 64 + 0 + 0 + 0 + 0 + 0 + 0 = 1984d.

**Converting Decimal Number to Binary Number.**

for whole numbers, integers, we have a method:

to convert a decimal number to binary number we divide it until quotient reaches 0, each time writing remainder of division.

1984/2 = 992 rem 0,

992/2 = 496 rem 0,

496/2 = 248 rem 0,

248/2 = 124 rem 0,

124/2 = 62 rem 0,

62/2 = 31 rem 0,

31/2 = 15 rem 1,

15/2 = 7 rem 1,

7/2 = 3 rem 1,

3/2 = 1 rem 1,

1/2 = 0 rem 1.

we have, reading from bottom-upwards: 11111000000b = 1984d.

for fractions (less than 1), we have a method:

having a number less than one, we multiply it by 2 amount of times equal to number of bits in which we wish to represent that a fraction.

after multiplication, if result is more or equal 1, we subtract 1 from it, taking following result as a base for following calculations (multiplications).

let's write number 0.8125d in binary notation using 5 bits. we'll use 5 multiplications.

0.8125 * 2 =

**1**.625,

0.625 * 2 =

**1**.25,

0.25 * 2 =

**0**.5,

0.5 * 2 =

**1**.0,

0.0 * 2 =

**0**.0.

reading from top-downwards whole parts of resulting calculations we write:

0.8125d = 0.11010b.

as another example, let's write number 0.625d in binary notation using 5 bits. we'll use 5 multiplications.

0.625 * 2 =

**1**.25,

0.25 * 2 =

**0**.5,

0.5 * 2 =

**1**.0,

0.0 * 2 =

**0**.0,

0.0 * 2 =

**0**.0.

reading from top-downwards whole parts of resulting calculations we write:

0.625d = 0.10100b.

not every number, for example 0.1d = 0.00011001100110011...., can be represented using a finite binary representation.

let's note that decimal notation is converted to binary notation separately for integer & fraction parts.

**Negative Binary Numbers.**

this notation is called U2 (U-two's complement).

to represent -45d in an 8-bit byte, we take 45d written in binary form using 8 bits, negate it, then add 1.

1. we have: 45d = 00101101b,

2. we negate 00101101b, then we have: 11010010b,

3. we add 1 to 11010010b, then we have: 11010011b = -45d.

let's note that depending on interpretation of this number, either as U2 or as an unsigned integer, we have either:

11010011b (U2) = -45d.

or

11010011b (ui) = 211d.

**Basic Binary Number Arithmetics.**

Addition.

binary number addition is almost same as decimal addition, except that we carry after reaching two, not ten.

for better understanding we'll use addition table.

+ | 0 | 1 |

0 | 0 | 1 |

1 | 1 | 10 |

let's note that in binary notation 1 + 1 = 10 (two), but 1 + 1 + 1 = 11 (three).

let's try an example with 243d + 178d = 421d using above table.

1111 1 <- carry bits |

11110011 = 243d |

+10110010 = 178d |

110100101 = 421d |

adding positive number to negative number written in U2 notation is performed in exactly the same way.

let's add 3d + (-3)d = 00000011b (ui) + 11111101b (U2).

11111111 <- carry bits |

00000011 = 3d |

+11111101 = (-3)d |

100000000 = 0d |

when adding U2 (when at least one of factors is in U2), we cut off most important (leftmost) bit of a result.

result of above operation is 0d not 256d.

Subtraction.

we'll use subtraction table for a better understanding.

a | 0 | 0 | 1 | 1 |

b | 0 | 1 | 0 | 1 |

a-b | 0 | 1^{*} | 1 | 0 |

* let's note that when we subtract 1 from 0 we must borrow (as in a decimal system), so in above table we got 1.

let's try to calculate 243d - 178d = 65d using above table:

11110011 = 243d |

-10110010 = 178d |

01000001 = 65d |

Multiplication.

we'll use also a multiplication table for a better understanding.

* | 0 | 1 |

0 | 0 | 0 |

1 | 0 | 1 |

let's try to calculate 9d * 243d = 2187d using above table.

1001 = 9d |

*11110011 = 243d |

11110011 |

00000000 |

00000000 |

11110011 |

100010001011 = 2187d |

it's noteworthy to mention about method of division & multiplication by 2.

these operations are performed by moving accordingly to right (division) or left (multiplication) a given binary number.

this is only valid for positive numbers.

for negative numbers results of that a bit-shift operation are not correct.

**BCD Code (Binary Coded Decimal).**

Packed BCD code.

it's a method of writing unsigned decimal integer numbers.

it allows for storing of two decimal digits in a single 8-bit byte.

more important number (leftmost) takes four more important bits of a byte, while less important number (rightmost) takes four less important bits of a byte.

a notation of 00100111 (BCD) means a number 27d (2 = 0010, 7=0111).

let's note that not every number is a valid notation in BCD.

for example: 11001000 is not a valid BCD notation, because more important (leftmost) half-byte contains a number 12, not a valid decimal digit.

Unpacked BCD code.

occasionally one can find so called 'unpacked BCD code', where one digit is coded using whole byte.

for example: 0000000100000010 = 12d.

**Hexadecimal Notation.**

it's a notation where base is number 16.

this means that every value in this system is measured using a sum of consecutively following powers of 16, multiplied by appropriate 'digits' in this system.

these are: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F; where A=10, B=11, C=12, D=13, E=14, F=15.

for example: 0A3Fh = A * 16

^{2}+ 3 * 16

^{1}+ F * 16

^{0}= 10 * 16

^{2}+ 3 * 16

^{1}+ 15 * 16

^{0}= 10 * 256 + 3 * 16 + 15 = 2623d.

why it's useful notation?

disadvantage of a binary notation is a big length of numbers.

hexadecimal number takes a little of space & can be easily converted to binary & other way around as well.

**Converting Binary to Hexadecimal.**

to convert binary number that way, we divide binary number (starting from right side) into fours of bits, that are then exchanged for their equivalents in the hexadecimal system.

for example:

1100 | 0011 | 1101 | 0101 | 1110 | 1111 |

C | 3 | D | 5 | E | F |

then we have: 0C3D5EFh = 110000111101010111101111b.

we can convert hexadecimal number to binary the same way ... exchanging each of hexadecimal system digits to fours of bits, then presenting them in a coherent form.

**Floating Point Numbers.**

this notation allows for writing a Real numbers with a degree of correctness.

number of bits determines how close to a desired number the written one can be.

there are four main types of floating point numbers, differing with size measured in bits.

they are named: single, real, extended, double.

single uses 4 8-bit bytes, extended uses 10 8-bit bytes.

basicly, number is written in a form: m * 10

^{e}, where m is called mantissa & e is called exponent (integer).

analogously, any number can be written in form: m * 2

^{e}, where e is a whole integer number again.

in practice, a 'single' number is written as:

s (1 bit) | exponent (8 bits) | mantissa (23 bits) |

s - sign, either 0 (+) or 1 (-),

e - exponent (we don't use U2, we add 127 to a value to determine sign & a value),

m - mantissa (unsigned binary; we skip initial 1, as every number starts with this).

value of a 'single' number is determined as follows:

if 0 < e < 255 | then value = (-1)*s*2^{e-127}*1.m, |

if e = 0 & m <> 0 | then value = (-1)*s*2^{-126}*0.m, |

if e = 0 & m = 0 | then value = 0, |

if e = 255 & m = 0 | then value = (-1)*s*Inf. |

if e = 255 & m <> 0 | then value = NaN. |

where:

- Inf means Infinity,

- NaN means Not a Number.

Source: [31].

see also, if You wish or need, ... : Abstraction Levels in Programming.