# Introduction to C / C++ Programming Number Systems - Binary, Octal, Hex

## Positional Number Systems

• We are all familiar with the tradiitonal base-10 number system, which uses 10 digits ( 0 to 9 ) and in which the positions increase in value by powers of 10 from right to left. For example, the number 487 is interepreted as 4 hundreds plus 8 tens plus 7 ones.
• Other number systems work similarly, using different numbers for their bases. In computer science we are particularly interested in binary, octal, and hexadecimal systems, which are base 2, 8, and 16 respectively.
• The relationship between these number systems can be seen in the following table, where the zero position refers to the rightmost digit of a number, and the ^ symbol represents exponentiation:
 Position Value in base: 10 2 8 16 0 10^0 = 1 2^0 = 1 8^0 = 1 16^0 = 1 1 10^1 = 10 2^1 = 2 8^1 = 8 16^1 = 16 2 10^2 = 100 2^2 = 4 8^2 = 64 16^2 = 256 3 10^3 = 1000 2^3 = 8 8^3 = 512 16^3 = 4,096 4 10^4 = 10,000 2^4 = 16 8^4 = 4,096 16^4 = 65,536 5 10^5 = 100,000 2^5 = 32 8^5 = 32,768 16^5 = 1,048,576 6 10^6 = 1,000,000 2^6 = 64 8^6 = 262,144 16^6 = 16,777,216 7 10^7 = 10,000,000 2^7 = 128 8^7 = 2,097152 16^7 = 268,435,456

## Unsigned Binary Integers

• Computers store all of their information in the form of electrica voltages, which are either "high" ( typically 5 volts ) or "low" ( typically 0 volts. )
• Sequences of high and low voltages can be interpreted as binary numbers, by assigning high voltages the value of 1 and low voltages of 0.
• Note that only two digits are used in binary systems, 0 and 1.
• So if a computer needed to store the decimal value 5 as a 4-digit binary number, It would need one 4 plus one 1, so the binary equivalent would be 0101, and the voltages stored would be low high low high.
• Similarly 13 would be stored as 1101 as a 4-digit binary number, and 42 as 00101010 as an 8-digit binary number.
• Each binary digit is refered to as a bit. Eight bits make up a byte, and four bits are called a nibble.
• The largest unsigned nibble is 1111 = 15, and the largest unsigned byte is 11111111 = 255.

## Signed Binary Integers

• If a bit pattern is to be interpreded as a signed number, then it can take on either positive or negative values.
• There are two ways to interpret signed binary integers:
1. The easy way is to simply interpret the most-significant bit ( the left most digit ) as the negative of the value it would have otherwise.
• So for example,the 4-bit number 1011 would now be interpreted as one negative 8 plus one 2 plus one 1, for a total of -5
2. The correct way is termed twos complement, which takes the negative of a number by inverting all of the bits ( converting 1s to 0s and vice versa ), and then adding 1 to the result.
• So for example, 1011 would first invert to 0100, and then add 1 to yield 0101, which is 5.
• This means that 1011 is the negative of 0101, i.e. -5, the same as we found the easy way.
• Twos complement is fast to implement in hardware, and has some other benefits.
• Because signed numbers use some of their available bit patterns for negative numbers, the magnitude of the largest possible number is about half that of unsigned numbers.
• Four bits ranges from 0 to 15 as unsigned numbers and from -8 to +7 as signed numbers.
• Eight bits ( one byte ) ranges from 0 to 255 signed and from -128 to +127 signed

## Octal Numbers

• When dealing with long strings of binary numbers it is usually more convenient to group them into sets of 3 or 4 bits, that can be represented as octal or hexadecimal numbers respectively.
• Three bit binary numbers range from 000 to 111, i.e. 0 to 7 in decimal. Accordingly octal digits range from 0 to 7.
• So the binary bit pattern 10110010101101011 would be grouped as 10 110 010 101 101 011, and then written in octal as 262553
• It is also possible to convert directly between octal and decimal using the powers of 8 shown in the table above.
• Octal ( and hexidecimal ) numbers are generally only interpreted as unsigned integers.

• When bits are grouped into sets of four, the range of values for each set ranges from 0000 to 1111, i.e. from 0 to 15.
• Since we now have 15 possible "digits", we need additional symbols for the decimal values from 10 to 15, so the letters A to f are used to represent those hexadecimal digits.
• The following table summarizes the binary, octal and hexidecimal values of the first 16 integers:

 Decimal Binary Octal Hexadecimal 0 0000 00 0 1 0001 01 1 2 0010 02 2 3 0011 03 3 4 0100 04 4 5 0101 05 5 6 0110 06 6 7 0111 07 7 8 1000 10 8 9 1001 11 9 10 1010 12 A 11 1011 13 B 12 1100 14 C 13 1101 15 D 14 1110 16 E 15 1111 17 F

## Fractional Numbers

• To express fractional numbers in decimal, one adds a decimal point to the right of the integer portion of the number, and then adds additional digits for decimal fractions.
• The first digit to the right of the decimal point is 10^-1 or tenths, the next is 10^-2 or hundredths, etc.
• Similarly a binary point can be added to the right of a binary integer, and additional binary digits added to represent binary fractions.
• The first digit to the right of the binary point is 2^-1 or halves, the next is 2^-2 or quarters, then 2^-3 or eighths, etc.
• so 1011.011 in binary would be 11.375 in decimal. ( 8 plus 2 plus 1 plus 1/4 plus 1/8 )
• Note that some mumbers that seem "even" in decimal cannot be represented exactly in binary. One such example is 0.1, i.e. one-tenth.
• Computers store fractional ( floating point ) numbers using the IEEE floating point standard. The details of the standard are beyond the scope of the course, but basically it uses 32 bits as follows:
• One bit to represent the sign of the number.
• Some of the bits, say 23 of them, to represent the digits of the number as an unsigned binary integer.
• The rest of the bits, say 8 of them, as an exponent to shift the binary point right or left as needed.
• Note that this allows a much broader range of numbers and fractions than a 32-bit integer, but because only some of the bits are used to represent the digits, it is less precise than a number in which all 32-bits are used for digits.
• Double precision numbers are floating point numbers that use 64 bits instead of 32, to cover a broader range of values at higher precision than ordinary floating point numbers.