9/22/15

Binary-Decimal-Hexadecimal Conversions.

Understanding various number notations (mostly it's Decimal, Binary & Hexadecimal; Octal occasionally as well) for numbers is important when learning or using low-level programming.

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 * 103 + 9 * 102 + 8 * 101 + 4 * 100.

number 1984.75 we can write as:

1984.75d = 1 * 103 + 9 * 102 + 8 * 101 + 4 * 100 + 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 * 210 + 1 * 29 + 1 * 28 + 1 * 27 + 1 * 26 + 0 * 25 + 0 * 24 + 0 * 23 + 0 * 22 + 0 * 21 + 0 * 20 = 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 * 162 + 3 * 161 + F * 160 = 10 * 162 + 3 * 161 + 15 * 160 = 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:

110000111101010111101111
 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 * 10e, where m is called mantissa & e is called exponent (integer).

analogously, any number can be written in form: m * 2e, 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) 

where:

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*2e-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.

1 comment:

  1. floating point numbers notation & arithmetic operations on these numbers were invented by Alan Turing in 1940.

    ReplyDelete