Bits and Numbers Relationship

Bits is what computers' are today. They holds a dual quantised value to either 0 and 1. It is similar to flipping a switch - 0 is off, 1 is on. Hence, it is simple enough for us to manipulate an action by simply flipping switches. That's how the basic of microcontroller works: you manipulate bits to switch on-and-off for certain switches. How, how can we use it to our advantage by relating it math? This section covers the historical overview about bits and math relationship.

Special Thanks

Special thanks and dedicated this post to Cherolyn Lexvold who inspired me to document this knowledge fragment. It's been a long time since I revise my textbook for computer science.

The Origin of 8-Bits

Bits started off as simple digital electronics, like switches that controls the house's ON/OFF light. Group 8 of them together into a panel, you controls 8 different sets of house lights individually. That was fun until the Base-2 mathematics came in: can we relate the switches together and represent something? That's where the explorations went in. For starters, they were playing with 8 sets of switches which now is known as 8-bits.

Base-2 and 8-Bits Numerical Representations

Since we have Base-2 mathematics, scientists began to map the entire 8-bits range with numbers. This gave us a (roughly) huge table of numbers like the following:

8-bits switches ==> Base10 Numbers
0 0 0 0 0 0 0 0 ==> 0
0 0 0 0 0 0 0 1 ==> 1
0 0 0 0 0 0 1 0 ==> 2
0 0 0 0 0 0 1 1 ==> 3
...
1 1 1 1 1 1 1 1 ==> 255

Hence, the first numerical number system is available for computing. 8-Bits is able to map numbers from 0 to 255. It mathematically obeys the Base10 to Base2 mathematical conversion and the positioning of the switches complies to the Base2 numbering position values. Scientists were happy and document this mapping as the first mathematical relationship.

What About Negative Values?

Now, in basic Mathematics, it's not just about positive numbers. We have negative numbers too. In numbers, negative numbers has a new positioning: the negative sign (-). Now we have a problem: every electronic chips uses 8-bits as a primary switch set. We can't add simply add 1 more bit just to do indications?!

After a long discussion, they decided that instead of altering the number of bits, we alters the numbering representations: use the most significant bit as indicator. Hence, a new set of numbering table emerges:

8-bits switches ==> Base10 Signed Numbers
0 1 1 1 1 1 1 1 ==> 127
...
0 0 0 0 0 0 1 1 ==> 3
0 0 0 0 0 0 1 0 ==> 2
0 0 0 0 0 0 0 1 ==> 1
0 0 0 0 0 0 0 0 ==> 0
1 0 0 0 0 0 0 0 ==> -0
1 0 0 0 0 0 0 1 ==> -1
1 0 0 0 0 0 1 0 ==> -2
1 0 0 0 0 0 1 1 ==> -3
...
1 1 1 1 1 1 1 1 ==> -127

Hence, we can know the sign when the most significant bit (in the above, the 8th bit is set):

0 0 0 0 0 0 0 0 ==> 0
1 0 0 0 0 0 0 0 ==> -0

This left us 7-bits for numbering. Mapping them up and we get a maximum of 127 of each sides.


But Electronics Do Not Care About Signs?

After solving one problem, another problem emerges: the existing numbering is working fine for electronic controls. Remember, we use every single bit to control every single set of light respectively. After taking into that consideration, the scientists decided to deduce 2 sets of numbering representations:

  • Without negative sign - now known as unsigned
  • With negative sign - now known as signed

Since we have different set of customers, it's better for them to choose for themselves.

The Need of 2-Complements

Of course, the scientists proceeded to explore mathematical operations. However, they immediately encountered a problem: the math does not adds up in Base2 numbering representation for signed numbers. Example, in Base10, 15 plus a negative 5 should equal to 10, so the math we usually write is:

  15 + (-5)
= 15 - 5
= 10

However, when it comes to Base2, if we switch the numbering, we get:

  00001111 + 10000101
= 10010100
= -20 (in base 10) # this is so wrong! It's not 10!

Therefore, there is the problem.


The Sign Simplification Problem

Apparently, in Base10, when we add a number to a negative number, we automatically simplify the actual operations to that number subtract the latter number without being aware of it. Hence, there is a "process" done. In electronics control, nothing is magic; all must submit to mathematics and logical operations. When you add, you add; you don't covert the operations. Also, it is required to retain its normal number representation. This means we can't distort the 5 as a fact that it is "negative" 5, not a new numbering symbol. Hence, scientists know they need to work it out backwards.


Messing With Overflow

Also, in digital electronics, it is actually allowed for overflow. When it happens, it becomes the beginning. Example, in unsigned numbering representation:

11111111 + 00000001
= (1) 00000000
= 00000000 (Overflow 1)

Hence, that gives a good trick to reset a number system (by ignoring the overflow since it's not needed for us).


Working Backwards

Working it backwards now, the following gives us:

  15 + (-5)  --> 00001111 + (?Must have 00000101 representation?)
= 15 - 5     --> 00001111 - 00000101
= 10         --> 00001010

Whenever a negative number is given, it must be so big that it causes an overflow when the resultant number is positive.

By working it out, the scientists found that the only representation for -5 is:

Final value with overflow is: (1)00001010
Number is negative, so -5 must have: 10000000                 -- (1)
To flip the sign into overflow, we need to at least 10000000  -- (2)
Working reversely, we get 11111011                            -- (3)
Test the number 00001111 + 11111011 = (1)00001010 = 00001010  -- (4)
∴, -5 = 11111011                                              -- (5)

Let's invert +5 in base2: NOT 00000101 = 11111010             -- (6)
(5) - (6): 11111011 - 11111010 = 00000001                     -- (7)
From (6) and (7),
∴,
-5 = 11111011
   = 11111010 + 00000001
-5 = NOT 00000101 + 00000001
-5 = NOT 5 + 1                                                -- (8)


The Discovery

From the above discovery, we can understand that all negative numbers be represented as NOT(positive number) + 1. Hence, testing this generated number yields:

  10 + (-7) = 3
= 00001010 + 11111001
= (1)00000011
= 00000011
= 3 (in Base10)

-15 + (-5) = -20
= 11110001 + 11111011
= (1)11101100
= 11101100
= 11101011 - 00000001
= NOT 00010100 - 0000001
= NOT (20) - 1 (in Base10)


Birth of 2-Complements

Hence, the correct signed number is born. For negative number, we need to NOT(positive number) + 1. This process that we subconsciously did it all the time, is now called "2 compliments", where we first compliment it (NOT-ing) then and 1.

-NUMBER = NOT(NUMBER) + 1


Correct Representations

With the new formulation, scientist began to re-tabulate all signed numbers, giving a new and correct signed numbering table:

8-bits switches ==> Base10 Signed Numbers
0 1 1 1 1 1 1 1 ==> 127
...
0 0 0 0 0 0 1 1 ==> 3
0 0 0 0 0 0 1 0 ==> 2
0 0 0 0 0 0 0 1 ==> 1
0 0 0 0 0 0 0 0 ==> 0
1 1 1 1 1 1 1 1 ==> -1
1 1 1 1 1 1 1 0 ==> -2
1 1 1 1 1 1 0 1 ==> -3
...
1 0 0 0 0 0 0 1 ==> -127
1 0 0 0 0 0 0 0 ==> -128

Where we now have signed number having the range of [127, -128]. Hence, the bits and math relationship are working together nicely.

Birth of Signed and Unsigned Numbers

Therefore, we concluded that for 8 bits numbering systems on bitwise, we have:

signed numbers, 8-bits, represented as int8 has a range of [127, -128].

unsigned numbers, 8-bits, represented as uint8, has a range of [0, 255].

That's how we found ourselves with int8 or uint8 in any programming languages. From that point onward, computer becomes a very powerful calculator.

Scaling Bitwise?

As technologies improved, increase the number of bits (normally by 2x), you get an even bigger ranges. Some are:

  • 16-bit has 65535 (uint16), and [-32768, 32767] (int16)
  • 32-bit has 4294967295 (uint32), and [-2147483648, 2147483647] (int32)

Multiplication and Division Operation

After dealing with number representations, scientists wonder can we push to it multiplication and division. Of course we can; provided we must understand how both of them works.

Multiplication

Multiplication is actually a looping additions. It's addition repeated by number of times. Example:

152 * 6 = 152 + 152 + 152 + 152 + 152 + 152 = 912

So similarly, on Base2,

101 * 11 = 101 + 101 + 101 = 1111

Division

Division is a bit tricky. It is actually taking a number (known as dividend), subtract another number (known as divisor), number of times (known as quotient), with the remaining values (known as remainder). Hence, you keep subtracting the dividend with the divisor until the remainder is less than the divisor, where you stop.

In case you wonder, this is how those names work together:

dividend (R‘) / divisor (D) = quotient (Q), remainder (R)
9 / 2 = 4, 1

Therefore, given an example:

11101011 / 101
----
Q) R‘       -  D  = R
1) 11101011 - 101 = 11100110
2) 11100110 - 101 = 11100001
3) 11100001 - 101 = 01011100
...
46) 00001010 - 101 = 00000101
47) 00000101 - 101 = 00000000 // stop since R is less than D, which is equal to 0
----
Quotient (Q) = 47 (Base10) = 00101111 (Base2)
Remainder (R) = 0 (Base10) = 00000000 (Base2)

This is also the reason why when any number divided by 0, you get an error instead of infinity. You will realize it takes forever to calculate Q and R and never gets a result at all. Yet, infinity by definition means so big that we can’t even count. It’s just too big.

Therefore, unable to calculate result simply does not mean “result is so big”: you can't equate an error to infinity.

With all 4 operations (add, subtract, multiply, and divide) made available, we made wonders for what we have today.

Wrapping Up

That's how bits relate to math. Beyond here, it's more of the application. Remember, microprocessor or microcontroller can be used as math calculator or simply an electronics switches. The choice is up to you to choose the unsigned or signed numbering representations.