Number Bases

From Compsci.ca Wiki

(Difference between revisions)
Jump to: navigation, search
(Hexidecimal)
 
(4 intermediate revisions not shown)
Line 78: Line 78:
When we add the decimal equivalents together using the addition we all know quite well, we get 205.
When we add the decimal equivalents together using the addition we all know quite well, we get 205.
-
=== Hexidecimal ===
+
=== Hexadecimal ===
Also known as "base 16."  Zero to nine are represented as one familiar with decimal would expect, while ten through fifteen are represented by A-F.
Also known as "base 16."  Zero to nine are represented as one familiar with decimal would expect, while ten through fifteen are represented by A-F.
Line 101: Line 101:
== The Obvious Pattern ==
== The Obvious Pattern ==
-
The pattern here should be obvious.  In number representations each digit represents that amount multipled by the based raised to the position of the digit from the right, starting from zero.
+
The pattern here should be obvious.  In number representations each digit represents that amount multipled by the base raised to the position of the digit from the right, starting from zero.
 +
 
 +
=== Sums ===
 +
 
 +
A further pattern to be noticed is that the maximum number that can be represented by n digits is 1 less than the smallest number that can be represented by n + 1 digits.  As an example, the largest decimal number that can be represented by three digits is 999.  This is exactly one less than 1,000, which is the smallest number than can be represented by four digits.
 +
 
 +
== Determining Representation ==
 +
 
 +
So far I've looked at how to understand number representations in terms of decimal, but many people find it more challenging to go the other way, particularly in an organized, algorithmic fashion.  But really, there are only two mathematical concepts a person needs to understand: integer division and modulus.
 +
 
 +
In integer division we disregard any remainder. 
 +
 
 +
{| style="text-align: center" border="1" cellpadding="5" cellspacing="0"
 +
|-
 +
! Numerator || Denominator || Result
 +
|-
 +
| 4 || 3 || 1
 +
|-
 +
| 6 || 7 || 0
 +
|-
 +
| 16 || 5 || 3
 +
|}
 +
 
 +
Modulus on the other hand is all about the remainder.
 +
 
 +
{| style="text-align: center" border="1" cellpadding="5" cellspacing="0"
 +
|-
 +
! Numerator || Denominator || Result
 +
|-
 +
| 4 || 3 || 1
 +
|-
 +
| 6 || 7 || 6
 +
|-
 +
| 16 || 5 || 1
 +
|-
 +
| 4 || 2 || 0
 +
|}
 +
 
 +
Let's consider a simple conversion: represent the decimal number 1 in binary.
 +
 
 +
We'll get the result of 1 mod b where b = 2.  Since we want position zero, this becomes 1 mod 2, which we know must be 1.  We'll then divide 1 by 2 and get zero.  Since we have zero remaining, we don't need any further digits to represent 1 in binary.
 +
 
 +
Let's consider a slightly more complex example.
 +
 
 +
{| style="text-align: center" border="1" cellpadding="5" cellspacing="0"
 +
|-
 +
! colspan="2" | Representing decimal number 234 in binary
 +
|-
 +
! Decimal || Modulo 2
 +
|-
 +
| 234 || 0
 +
|-
 +
| 117 || 1
 +
|-
 +
| 58 || 0
 +
|-
 +
| 29 || 1
 +
|-
 +
| 14 || 0
 +
|-
 +
| 7 || 1
 +
|-
 +
| 3 || 1
 +
|-
 +
| 1 || 1
 +
|-
 +
| 0 || 0
 +
|-
 +
! colspan="2" | Final result = 11101010
 +
|}
 +
 
 +
=== Programming ===
 +
 
 +
When we consider the repetitive nature of this process, it should be quite easy to map it to code in a programming language using either procedural iteration or recursion.
 +
 
 +
==== Python 3.0 Example ====
 +
 
 +
<pre>>>> def to_binary(n):
 +
...    digits = []
 +
...    while n > 0:
 +
...            digits.insert(0, n % 2)
 +
...            n //= b
 +
...    return digits
 +
...
 +
>>> to_binary(4)
 +
[1, 0, 0]
 +
>>> to_binary(234)
 +
[1, 1, 1, 0, 1, 0, 1, 0]</pre>
 +
 
 +
==== Making it more generic ====
 +
 
 +
This algorithm doesn't need to specify the base at all.
 +
 
 +
==== More Generic Python 3.0 Example ====
 +
 
 +
<pre>>>> def to_base(n, b):
 +
...    digits = []
 +
...    while n > 0:
 +
...            digits.insert(0, n % b)
 +
...            n //= b
 +
...    return digits
 +
...
 +
>>> to_base(4, 2)
 +
[1, 0, 0]
 +
>>> to_base(234, 2)
 +
[1, 1, 1, 0, 1, 0, 1, 0]</pre>
 +
 
 +
==== (Tail) Recursive O'Caml Example ====
 +
 
 +
<pre>        Objective Caml version 3.11.0
 +
 
 +
# let to_base n b =
 +
        let rec helper n acc =
 +
                if n = 0 then acc
 +
                else helper (n / b) ([n mod b] @ acc)
 +
        in
 +
                helper n [];;
 +
val to_base : int -> int -> int list = <fun>
 +
# to_base 4 2;;
 +
- : int list = [1; 0; 0]
 +
# to_base 234 2;;
 +
- : int list = [1; 1; 1; 0; 1; 0; 1; 0]
 +
#</pre>

Latest revision as of 06:14, 1 April 2009

Contents

Number Bases

In math and computer science, numbers are often taken for granted, but understanding them is absolutely essential. The first thing to understand about numbers is how they're written, and for that we have to understand number bases.

Decimal

The base we're all raised on these days is base 10. We all know that in decimal representation "1" is one, "2" is two" and "456" is four hundred and fifty-six, but how does this actually work? How do we know that that "4" being where it indicate four hundred and how does the 5 being where it is indicate fifty?

In the case opf 456, we can see this as follows.

456 broken down
4 x 100 5 x 10 6 x 1

Of course, if you know anything about exponents, you should notice that there's a very simple pattern here.

456 broken down further
4 x 100 5 x 10 6 x 1
4 x 102 5 x 101 6 x 100

We can factor this out further

Factoring out the base
4 x 100 5 x 10 6 x 1
4 x 102 5 x 101 6 x 100
4 x b2 5 x b1 6 x b0
where b = 10

Now we should be able to extrapolate this pattern out to deal with decimal numbers of any length.

Binary

Binary is a very formal way of saying "base 2." In base 2 the only digits at our disposal for representations are 0 and 1. Let's break down a binary number.

Breakdown of 11001101
1 x 128 1 x 64 0 x 32 0 x 16 1 x 8 1 x 4 0 x 2 1 x 1
1 x 27 1 x 26 0 x 25 0 x 24 1 x 23 1 x 22 0 x 21 1 x 20
1 x b7 1 x b6 0 x b5 0 x b4 1 x b3 1 x b2 0 x b1 1 x b0
where b = 2
Equivalent Decimal Representation
128 64 0 0 8 4 0 1

When we add the decimal equivalents together using the addition we all know quite well, we get 205.

Hexadecimal

Also known as "base 16." Zero to nine are represented as one familiar with decimal would expect, while ten through fifteen are represented by A-F.

Breakdown of A9
A x 16 9 x 1
A x 161 9 x 160
A x b1 9 x b0
where b = 16
Equivalent Decimal Representation
160 9

The Obvious Pattern

The pattern here should be obvious. In number representations each digit represents that amount multipled by the base raised to the position of the digit from the right, starting from zero.

Sums

A further pattern to be noticed is that the maximum number that can be represented by n digits is 1 less than the smallest number that can be represented by n + 1 digits. As an example, the largest decimal number that can be represented by three digits is 999. This is exactly one less than 1,000, which is the smallest number than can be represented by four digits.

Determining Representation

So far I've looked at how to understand number representations in terms of decimal, but many people find it more challenging to go the other way, particularly in an organized, algorithmic fashion. But really, there are only two mathematical concepts a person needs to understand: integer division and modulus.

In integer division we disregard any remainder.

Numerator Denominator Result
4 3 1
6 7 0
16 5 3

Modulus on the other hand is all about the remainder.

Numerator Denominator Result
4 3 1
6 7 6
16 5 1
4 2 0

Let's consider a simple conversion: represent the decimal number 1 in binary.

We'll get the result of 1 mod b where b = 2. Since we want position zero, this becomes 1 mod 2, which we know must be 1. We'll then divide 1 by 2 and get zero. Since we have zero remaining, we don't need any further digits to represent 1 in binary.

Let's consider a slightly more complex example.

Representing decimal number 234 in binary
Decimal Modulo 2
234 0
117 1
58 0
29 1
14 0
7 1
3 1
1 1
0 0
Final result = 11101010

Programming

When we consider the repetitive nature of this process, it should be quite easy to map it to code in a programming language using either procedural iteration or recursion.

Python 3.0 Example

>>> def to_binary(n):
...     digits = []
...     while n > 0:
...             digits.insert(0, n % 2)
...             n //= b
...     return digits
...
>>> to_binary(4)
[1, 0, 0]
>>> to_binary(234)
[1, 1, 1, 0, 1, 0, 1, 0]

Making it more generic

This algorithm doesn't need to specify the base at all.

More Generic Python 3.0 Example

>>> def to_base(n, b):
...     digits = []
...     while n > 0:
...             digits.insert(0, n % b)
...             n //= b
...     return digits
...
>>> to_base(4, 2)
[1, 0, 0]
>>> to_base(234, 2)
[1, 1, 1, 0, 1, 0, 1, 0]

(Tail) Recursive O'Caml Example

        Objective Caml version 3.11.0

# let to_base n b =
        let rec helper n acc =
                if n = 0 then acc
                else helper (n / b) ([n mod b] @ acc)
        in
                helper n [];;
val to_base : int -> int -> int list = <fun>
# to_base 4 2;;
- : int list = [1; 0; 0]
# to_base 234 2;;
- : int list = [1; 1; 1; 0; 1; 0; 1; 0]
#
Personal tools