Friday, November 25, 2011

Numbers: binary, decimal, hexadecimal


Numbers used by computers and by extension by programming languages can be represented in different radix (base). Usually, the decimal notation is the most convenient - specially for human beings - but in certain circumstances, it's better to use the binary or hexadecimal notations.


1- Binary notation

Computers work in binary and the elementary unit is the bit (containing 0 or 1). Thus, the binary notation [Wikipedia] is interesting to see how a computer stores numbers in its memory.

In JavaScript, the function String(2) allows the binary conversion. Just, write this small script.

let value=100;
IJ.log(` Value (base 10): ${value}`);
IJ.log(` Value (base 2):  ${value.toString(2)}`);

Two lines are displayed in the Log window:
Value (base 10): 100
Value (base 2): 1100100
To convert binary numbers into decimal, the general formula is:

k corresponds to the bit position in the binary number. By convention, the bit #0 is the rightmost digit (bit #n, the leftmost). Thus, in our example, the decimal conversion of 1100100 yields:
1100100(2) = 1x26 +1x25 +0x24 +0x23 +1x22 +0x21 +0x20 = 100(10)

2- Hexadecimal notation

Binary representation isn't very convenient because, there are a lot of digits. In computer science, the hexadecimal (base 16) is often used, because this is more compact than the binary and has some interesting properties [Wikipedia].
In this base (or radix), each digit has a value comprised between 0 to 15 (24-1). They are represented by the following symbols:
base 16 0 1 2 3 4 5 6 7 8 9  A  B  C  D  E  F
base 10 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
In this base, each hexadecimal digit corresponds to 4 bits. For example, 1111(2) = F(16), 0110(2)=A(16), and 0100(2)=8(16).
To summarize the various notations, the number of digits required to encode 8 bits is
  • base 2: 8 digits
  • base 10: 3 digits
  • base 16: 2 digits

base 10   0   255
base 2    0 11111111
base 16   0    FF

2-1- Hexadecimal conversion

To convert a decimal number to hexa (or binary), calculate the remainder of successive euclidean divisions by the radix (here, 16) as shown in the Fig.1.
Fig.1: Euclidean divisions to convert 141 into a hexadecimal numbers. The remainders are 13 and 8 yielding 141 = 8*161 + 13*160
Now, just look at the remainders, here they are 13 and 8. 13 corresponds to the symbol D in base 16 and because this is the first division, its position is the rightmost. Thus, in hexadecimal, our number is:
141(10) = 8 * 161 + 13 * 160  = 8D(16)
2-2- Hexadecimal display toString(16)
Rather than calculating divisions (yes! with a paper and a pen), it's more convenient to use ImageJ programming language...

To display numbers in hexadecimal, use the function toString(16) as follows:

IJ.log(`Value (16): 0x${value.toString(16)}`);

Usually in programming languages (like JavaScript),a hexadecimal number is prefixed by a "0x" (zero followed by the 'x' character). In the web (html, css,etc.), the colors are represented by a hexadecimal number with the prefix "#" (number sign or hash [Wikipedia]).
The binary and hexadecimal notations are useful in combination with bit operators (shift and logical). In ImageJ, the extraction of the red, green, and blue values of a color is an example of hexadecimal notation and bit operators [see post].

No comments:

Post a Comment