ex Computational Linear Algebra, Part 2: Numerical systems (Mathematica)
$Post := If[MatrixQ[#1], MatrixForm[#1], #1] & (* outputs matricies in MatrixForm*) Remove[ "Global`*"] // Quiet (* remove all variables *)

In daily life, the Hindu-Arabic decimal system (a 10-based numbering system) with 10 digits (from 0 to 9) is used to express integer, rational, and irrational numbers. Europe replaced Latin symbols with this system in 13th century after publication of Liber Abaci book by Leonardo Fibonacci in 1202.

Numerical Systems

From early childhood, we learned to count, first with and then without fingers. If you remember the time when everybody loved you, you recall learning numbers that are called natural numbers and, taken together, they form the set of natural numbers,

\[ \mathbb{N} = \left\{ 0, \ 1, \ 2, \ 3, \ \ldots \right\} . \]
The negations or additive inverses of the positive natural numbers are referred to as negative integers. The set of all integers is often denoted by
\[ \mathbb{Z} = \left\{ 0, \ \pm 1, \ \pm 2, \ \pm 3, \ \ldots \right\} . \]
The word "integer" comes from the Latin integer meaning "whole." Besides decimal system, several numbering systems with different bases are incorporated into digital computer hardware to interpret and communicate data between its components. Binary (base 2), ternary (base 3), octal (base 8), and hexadecimal (base 16) numbering systems are the most commonly used.

Some rational numbers can be written in decimal form as

\[ \mathbb{Q} \ni \left( a_n \cdots a_1 a_0 . b_1 \cdots b_m \right)_{10} = \sum_{k=0}^n a_k 10^k + \sum_{i=1}^m b_i 10^{-i} , \]
where the dot separated 𝑎's from b's is a decimal period separating the inter part from its fractional part.

In computer science, an integer is a datum of integral data type, a data type that represents some range of mathematical integers. Integral data types may be of different sizes and may or may not be allowed to contain negative values. Integers are commonly represented in a computer as a group of binary digits (bits). The size of the grouping varies so the set of integer sizes available varies between different types of computers. Computer hardware nearly always provides a way to represent a processor register or memory address as an integer.

In the decimal number system, an integer is expressed as a polynomial having one of the ten digits ranging from 0 to 9 as coefficients.

\begin{align*} \mathbb{N} \ni N &= \left( a_n a_{n-1} a_{n-2} \cdots a_1 a_0 \right)_{10} \\ &= a_n \times 10^n + a_{n-1} \times 10^{n-1} + \cdots + a_1 \times 10 + a_0 \\ &= \sum_{k=0}^n a_k \times 10^k . \end{align*}
For example, 2357 is represented as 2×10³ + 3×10² + 5×10¹ + 7×10⁰.

Note the use of the dot product in the code below

10^# & /@ {3, 2, 1, 0} {2, 3, 5, 7} . %
{1000, 100, 10, 1}
2357
Clear[n, k, a0, a1, a2, a3]; Reverse[PowerExpand[\!\( \*UnderoverscriptBox[\(\[Sum]\), \(k = 0\), \(n\)]\( \*SubscriptBox[\(a\), \(k\)]* \*SuperscriptBox[\(10\), \(k\)]\)\)] /. n -> 4]
Subscript[a, 0] + 10 Subscript[a, 1] + 100 Subscript[a, 2] + 1000 Subscript[a, 3] + 10000 Subscript[a, 4]

Wolfram code can be generalized into a function to handle any size integer. Note this function only works properly for positive integers. Below we add a character in the middle of our last example.

intNum[num_ : Integer] := Sum[Reverse[IntegerDigits[num]][[k + 1]]*10^k, {k, 0, Length[Reverse[IntegerDigits[num]]] - 1}]; intNum[43057]
43057

Computers can deal with a very limited subset 𝔽 of rational numbers, denoted by ℚ. A positive rational number has an integer (N) and a fractional part (F). The fractional part is written as a decimal fraction.

\begin{align*} \mathbb{Q} \ni F &= \left( .b_1 b_2 b_3 \cdots b_{m-1} b_m \right)_{10} \\ &= b_1 \times 10^{-1} + b_2 \times 10^{-2} + \cdots + b_{m-1} \times 10^{-m+1} + b_m \times 10^{-m} \\ &= \sum_{i=1}^m b_i \times 10^{-i} , \end{align*}
where each bi takes one of the values from 0 to 9. For instance,
\begin{align*} \left( 0.357 \right)_{10} &= 3 \times 10^{-1} + 5 \times 10^{-2} + 7 \times 10^{-3} \end{align*}

The input supplied to digital computers is in decimal format, but the digital computers process any type of numeric data, letters, and special symbols in discrete form as pulses sent by electronic components. For instance, the state of an electrical pulse is interpreted as 1 for a high voltage (on) or 0 for a low voltage (off ). This concept can be thought of as switching an electric circuit on and off. Hence, digital computers are designed to read and interpret data in binary form as a sequence of on’s (1’s) and off ’s (0’s). In other words, devices based on binary (on/off logic) can be constructed, and all forms of data can be expressed in a binary system.

Computers use bits (binary digit) to represent information. A bit is the basic unit of storage in a computer, and it is defined as a binary, which is 0 or 1. A byte is a group of eight bits used to represent a character, and it is the basic unit for measuring memory size in computers. Two or more bits are referred to as a word.

A binary number system has two symbols: 0 and 1, called bits. We shall designate a binary number with a suffix B or subscript 2. It is also a positional notation, for example,

\begin{align*} x &= 10110B = \left( 10110 \right)_2 = 10000B + 0000B + 100B + 10B + 0B \\ &= 1 \times 2^4 + 0×2^3 + 1×2^2 + 1×2^1 + 0×2^0 . \end{align*}
1*2^4 + 0*2^3 + 1*2^2 + 1*2^1 + 0*2^0
22
The Wolfram function FromDigits permits a base number as the second argument
FromDigits[{1, 0, 1, 1, 0}, 2]
22

The numbers with fractional parts are expressed as

\[ \left( 0.125 \right)_{10} = ( 0.001 )_2 = 0 \times 2^{-1} + 0 \times 2^{-2} + 1 \times 2^{-3} , \]
and
\begin{align*} \left( 0. 111 \right)_{10} &= \left( 0. \overline{000111} \right)_2 = 0 \times 2^{-1} + 0 \times 2^{-2} + 0 \times 2^{-3} \\ & \qquad + 1 \times 2^{-4} + 1 \times 2^{-5} + 1 \times 2^{-6} + 0 \times 2^{-7} + \cdots , \end{align*}
where overline denotes periodic expansion of the group of digits. So we see that the latter binary number is represented as an infinite series that would be truncated in any computer.

Hexadecimal number system uses 16 symbols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, and F, called hex digits. Since each hex digit has a weight of power 16, to convert from hexadecimal we use the sum of the product of each digit with its positional value by multiplying each digit from the left with 160, 16¹, 16², 16³ and from the right 16-1, 16-2, 16-3 It is a positional notation, for example,

\[ A3DH = A00H + 30H + DH = 10×16^2 + 3×16^1 + 13×16^0 \]
and
\[ \left( 0.21875 \right)_{10} = ( 0.38 )_{16} = 3 \times 16^{-1} + 8 \times 16^{-2} . \]
3*16^-1 + 8*16^-2 // N
0.21875
ResourceFunction["HexStringToReal", ResourceSystemBase -> "https://www.wolframcloud.com/obj/resourcesystem/api/1.0"]["A3DH"]
ResourceFunction["HexStringToReal"]["A3DH", {11, MachinePrecision}]
We shall denote a hexadecimal number (in short, hex) with a suffix H. Each hexadecimal digit is also called a hex digit. Most programming languages accept lowercase 'a' to 'f' as well as uppercase 'A' to 'F'.

Computers uses binary system in their internal operations, as they are built from binary digital electronic components with 2 states - on and off. However, writing or reading a long sequence of binary bits is cumbersome and error-prone (try to read this binary string: 1011 0011 0100 0011 0001 1101 0001 1000B, which is the same as hexadecimal B343 1D18H). Hexadecimal system is used as a compact form or shorthand for binary bits. Each hex digit is equivalent to 4 binary bits, i.e., shorthand for 4 bits, as follows

Hexadecimal Binary Decimal
0 0000 0
1 0001 1
2 0010 2
3 0011 3
4 0100 4
5 0101 5
6 0110 6
7 0111 7
8 1000 8
9 1001 9
A 1010 10
B 1011 11
C 1100 12
D 1101 13
E 1110 14
F 1111 15

Converting hexadecimal to binary is done in two methods, one is with a conversion table and another one is without a conversion table. WE show both approaches in the following example.    

Example 1: Method 1: Convert Hexadecimal to Binary with Conversion Table.

To convert a hexadecimal number to binary with a conversion table, we use the above table. We first convert the hexadecimal to decimal by obtaining the equivalent of the decimal number of each digit by looking at the table. We convert that decimal number to binary by looking at the same table. Finally, to obtain the binary number we combine the digits together. Let us look at an example.

Convert hexadecimal (67F)16 to binary.

Looking at the conversion table, find the equivalent of each digit to decimal. \[ 6 = \left( 6 \right)_{10} , \quad 7 = \left( 7 \right)_{10} , \quad F = \left( F \right)_{10} . \] Once the decimal of each digit is obtained, looking at the conversion table convert each decimal number to binary. \begin{align*} \left( 6 \right)_{10} &= (0110)_2 , \\ (7)_{10} &= (0111)_2 , \\ (F)_{10} &= (1111)_2 . \end{align*} Combine all the binary numbers together to obtain the final one. \[ (67F)_{16} = (011001111111)_2 . \]

Method 2: Convert Hexadecimal to Binary without Conversion Table.

This method requires both multiplication and division of numbers using the respective base numbers. The hexadecimal base number is 16, the base number of a decimal number is 10, and the base of a binary number system is 2. We multiply each digit with 16n-1, where the digit is in its nth position to obtain the decimal number. Once the digits are converted, we divide the decimal number by 2 by keeping the remainder aside and dividing the quotient by 2 until we arrive at zero. Finally, to obtain the binary number we arrange the remainders from bottom to top. Let us look at an example.

Convert (76)16 to decimal by multiplying each digit with 16n-1. Multiply it \begin{align*} (76)_{16} &= 7 × 16^{2-1} + 6 × 16^{1-1} \\ (76)_{16} &= 7 × 16^1 + 6 × 16^0 \\ (76)_{16} &= 7 × 16 + 6 × 1 \\ (76)_{16} &= 112 + 6 \\ (76)_{16} &= 118 \end{align*} Therefore, (76)16 = (118)10 .

Convert (118)10 to a binary number by dividing the number by 2 until the quotient is zero.

2 118     0
2 59 1
2 29 1
2 14 0
2 7 1
2 3 1
2 1 0

Hence, (76)16 = (1110110)2.

We check the answer with Mathematica:

BaseForm[118, 2]
1110110₂
and
BaseForm[118, 16]
7616
For instance,
BaseForm[1118, 16]
45e16

Conversion from Hexadecimal to Binary: Replace each hex digit by the 4 equivalent bits (as listed in the above table); for examples,

\begin{align*} A3C5H &= 1010 0011 1100 0101B \\ 102AH &= 0001 0000 0010 1010B \end{align*}
Mathematica confirms:
IntegerString[FromDigits["A3C5", 16], 2]
1010001111000101
and
IntegerString[FromDigits["102A", 16], 2]
"1000000101010"
   ■
End of Example 1

It is important to note that hexadecimal number provides a compact form or shorthand for representing binary bits.

The Octal system, which is also used to make any binary information more compact, is not as popular or common as hex or binary systems. An octal number is made up of digits ranging from 0 to 7. The octal system groups binary numbers into triplets instead of quartets. For instance, 125 in the octal system is expressed as

\[ \left( 125 \right)_{10} = \left( 175 \right)_{8} = 1 \times 8^1 + 7 \times 8^2 + 5 \times 8^3 \]
and
\[ \left( 0.21875 \right)_{10} = \left( 0.16 \right)_{8} = 1 \times 8^{-1} + 6 \times 8^{-2} . \]
BaseForm[0.21875, 8]
0.168

Convert Hexadecimal to Octal

Conversion of Hexadecimal to Octal is done in two steps i.e. first convert the hexadecimal number to decimal number and then convert it to an octal number. Let us look at an example to understand this method better.    

Example 2: Let us convert (AE5)16 to Octal. \begin{align*} (AE5)_{16} &= A × 16^2 + E × 16^1 + 5 × 16^0 \\ (AE5)_{16} &= 10 × 16^2 + 14 × 16^1 + 5 × 16^0 \end{align*} Convert the symbols to digits looking at the hexadecimal to decimal conversion table used above \begin{align*} (AE5)_{16} &= 10 × 256 + 14 × 16 + 5 × 1 \\ (AE5)_{16} &= 2560 + 224 + 5 \\ (AE5)_{16} &= (2789)_{10} \end{align*}
IntegerString[FromDigits["AE5", 16], 10]
"2789"
Convert the decimal number to octal by dividing it by 2 until the quotient is 0.
2789/8 = 348 remainder is     5
348/8 = 43 remainder is 4
43/8 = 5 remainder is 3
5/8 = 0 remainder is 5

Therefore, (AE5)16 = (5345)8 and (2789)10 = (5345)8.
BaseForm[2789, 8]
53458
We check with Mathematica:
IntegerString[FromDigits["AE5", 16], 8]
"5345"
hexToBinary[hex_String] := IntegerString[FromDigits[hex, 16], 2]
binaryToOctal[binary_String] := IntegerString[FromDigits[binary, 2], 8]
First convert hexadecimal to binary:
binary = hexToBinary["AE5"]
"101011100101"
Then convert the binary to octal:
octal = binaryToOctal[binary]
5345
   ■
End of Example 2

Convert Hexadecimal to Decimal

Hex is useful because large numbers can be represented using fewer digits. For example, color values and MAC addresses are often represented in hex. Additionally, hex is easier to understand than binary. Programmers often use hex to represent binary values as they are simpler to write and check than when using binary.

Converting hexadecimal to decimal is done in a similar manner as the previous two i.e., multiply each digit with the power of 16. Let us take an example.    

Example 3: Convert (DC24)16 to decimal.

Solution: \begin{align*} (DC24)_{16} &= D ×16^3 + C × 16^2 + 2 × 16^1 + 4 × 16^0 \\ (DC24)_{16} &= 13 ×16^3 + 12 × 16^2 + 2 × 16^1 + 4 × 16^0 \\ & \qquad\qquad (\mbox{convert the symbols to digits looking at the hexadecimal to decimal conversion table used above}) \\ (DC24)_{16} &= 13 × 4096 + 12 × 256 + 2 × 16 + 4 × 1 \\ (DC24)_{16} &= 53248 + 3072 + 32 + 4 \\ (DC24)_{16} &= 56356 \end{align*} Therefore, the decimal equivalent of (DC24)16 = (56356)10.

FromDigits["DC24", 16]
56356
.    ■
End of Example 3

Convert Binary to Hexadecimal

To convert binary to hexadecimal we use the conversion table used in the previous section. Let us look at an example for a better understanding.    
Example 4: Convert (11001111011)₂ to Hexadecimal.

Solution: For hexadecimal, the binary digits are expressed in 4. Hence, every 4 digit in binary becomes one 1 digit in hexadecimal. By looking at the conversion table we get, \[ 0110 = 6, \qquad 0111 = 7, \qquad 1011 = B . \] We arrange the numbers together to get the final number.

Therefore, (11001111011)₂ = (67B)16.

.    ■
End of Example 4

Convert Octal to Hexadecimal

To convert octal to hexadecimal, we first convert the octal number to binary number then to hexadecimal number. Octal to Binary has a different conversion table as the 3 binary digits make 1 octal digit. The conversion table is:

Octal to Binary Conversion Table
Octal Binary Decimal
0 000 0
1 001 1
2 010 2
3 011 3
4 100 4
5 101 5
6 110 6
7 111 7

   
Example 5: Convert (141)8 to hexadecimal

Solution: Looking at the table, we can convert each octal digit to binary. \begin{align*} 1 &= 001 , \\ 4 &= 100 , \\ 1 &= 001 \end{align*} Hence, (141)8 = (001100001)₂.

By looking at the binary to hexadecimal conversion table we get, \begin{align*} 0110 &= 6, \\ 0001 &= 1 \end{align*} (the zero on the left of the last digit can be removed or added according to the requirement)

Therefore, (141)8 = (61)16.

.    ■
End of Example 5

Convert Decimal to Hexadecimal

The decimal to hexadecimal conversion is done by using the base number of hexadecimal that is 16 so the number needs to be divided by 16 until the quotient is zero. Let us look at an example.    
Example 6: Convert (859)10 to hexadecimal.

Solution: Divide 859 by 16 until the quotient is zero.

859/16 = 53 remainder is     11
53/16 = 3 remainder is 5
3/16 = 0 remainder is 3

Therefore, (AE5)16 = 859.
BaseForm[859, 16]
35b16
Additionally, we write a subroutine explicitly inplemented the module command.
decimalToHexSteps[n_Integer] := Module[{quotient, remainder, remainders = {}, hexDigits}, quotient = n; While[quotient > 0, remainder = Mod[quotient, 16]; AppendTo[remainders, remainder]; quotient = Quotient[quotient, 16]; ]; hexDigits = remainders /. {10 -> "A", 11 -> "B", 12 -> "C", 13 -> "D", 14 -> "E", 15 -> "F"}; StringJoin[ToString /@ Reverse[hexDigits]] ]
We check our answer with this subroutine:
decimalToHexSteps[859]
35b16
   ■
End of Example 6

 

 

  1. <
  2. /ol>