========================================
Converting to/from hexadecimal (base 16)
========================================
-Ian! D. Allen - idallen@idallen.ca - www.idallen.com
The following link is a very good explanation and procedure for converting
hexadecimal to decimal, including handling both unsigned numbers and
two's complement negative numbers using bit flipping and adding one:
http://www.madsci.org/posts/archives/2000-02/950277263.Cs.r.html
Converting a negative two's complement number written in binary, octal,
or hexadecimal, to decimal usually means flipping all the bits (doing a
one's complement) and then adding one, converting the result to a positive
number, and then putting a minus sign in front of the positive result.
Since it's tedious to convert hex to binary, flip the bits, add one,
then multiply it out to get decimal, here is a nice table that lets you
"flip" (do a one's complement) on any hex digit directly:
One's Complement (Bit-Flip) Table for Hexadecimal
-------------------------------------------------
0 <--> F ( 0000 <--> 1111 )
1 <--> E ( 0001 <--> 1110 )
2 <--> D ( 0010 <--> 1101 )
3 <--> C ( 0011 <--> 1100 )
4 <--> B ( 0100 <--> 1011 )
5 <--> A ( 0101 <--> 1010 )
6 <--> 9 ( 0110 <--> 1001 )
7 <--> 8 ( 0111 <--> 1000 )
(You can create the above bit-flip table quickly by simply "folding"
a list of 16 hex digits in half - write the hex digits down one side
and then up the other side. The sum of any row is "F" [15].)
Find the hex digit you are complementing (bit flipping) in the table,
and replace it by the other number on the same line: 4A23 becomes B5DC.
Once you've flipped the bits, you can complete the twos complement
conversion process by adding one to the bit-flipped result.
Another way to flip the bits is to subtract from -1, all bits on,
e.g. FFFF - 4A23 = B5DC and FFFF - B5DC = 4A23
EXAMPLE 1: Convert two's complement 16-bit hex A2C9h to decimal.
----------
Step 1: Check the sign. If negative, make it positive and save the sign.
A2C9 is negative (the sign bit is on, since "A" = 1010 binary)
Use the table on A2C9 to flip the bits in each hex digit,
giving 5D36 which is the one's complement,
and then add one +1
giving 5D37 (a positive number, since "5" is 0101 binary)
Step 2: multiply out the powers of 16 for each hex digit
5 times 16**3 = 5 times 4096 = 20480
D times 16**2 = 13 times 256 = 3328
3 times 16**1 = 3 times 16 = 48
7 times 16**0 = 7 times 1 = 7
Add them all up and get 23863
Step 3: put back the sign (saved from Step 1)
Answer -23863 (negative)
EXAMPLE 1B: Convert decimal -23863 to two's complement 16-bit hex.
-----------
Step 1: Check the sign. If negative, make positive and remember to
convert from positive hex to negative hex at the end.
-23863 is negative. Save the sign and work on the positive number.
Step 2: Convert +23863 (positive/unsigned) to hex by factoring out
powers of sixteen. What are the powers of sixteen?
16^0 = (2^4)^0 = 2^0 = 1
16^1 = (2^4)^1 = 2^4 = 16
16^2 = (2^4)^2 = 2^8 = 256
16^3 = (2^4)^3 = 2^12 = 4096
16^4 = (2^4)^4 = 2^16 = 65536
65536 [16^4] is too big for 23863, so we know that we will have only
four hex digits in our answer, from 16^3 down to 16^0.
Subtract each successive power of 16:
23863 minus 5 times 4096 [16^3] equals 23863 - 20480 = 3383
3383 minus 13 times 256 [16^2] equals 3383 - 3328 = 55
55 minus 3 times 16 [16^1] equals 55 - 48 = 7
7 minus 7 times 1 [16^0] equals 7 - 7 = 0 --> DONE
Step 3: Write down the powers of 16 as hexadecimal digits.
5 -> 5 times 16^3 A=10, B=11, C=12, D=13, E=14, F=15
13 -> D times 16^2
3 -> 3 times 16^1
7 -> 7 times 16^0
Step 4: Assemble the hex digits into a hexadecimal number, with the smallest
powers of 16 on the right and the biggest (most significant) on the left.
Remembering that the number was negative, Make the positive hex number
into a negative hex number (twos complement) by complementing the bits
(using the bit flip table) and adding one:
5D37 -> bit flip (using the hex bit flip table) -> A2C8
A2C8 plus one is A2C9 which is the answer.
ANSWER: decimal -23863 converted to 16-bit two's complement hex is A2C9
EXAMPLE 2: Convert unsigned 16-bit hex A2C9 to decimal.
----------
Step 1: Unsigned numbers are all positive. No need to check any sign.
Step 2: multiply out the powers of 16 for each hex digit
A times 16**3 = 10 times 4096 = 40960
2 times 16**2 = 2 times 256 = 512
C times 16**1 = 12 times 16 = 192
9 times 16**0 = 9 times 1 = 9
Add them all up and get TOTAL 41673
Step 3: put back the sign (saved from Step 1)
Unsigned numbers are always positive.
Answer 41673
EXAMPLE 2B: Convert unsigned decimal 41673 to 16-bit hex.
-----------
Step 1: Check the sign. Number is unsigned - no sign bit. No bit flip needed.
Step 2: Convert 41673 (positive/unsigned) to hex by factoring out
powers of sixteen. What are the powers of sixteen?
16^0 = (2^4)^0 = 2^0 = 1
16^1 = (2^4)^1 = 2^4 = 16
16^2 = (2^4)^2 = 2^8 = 256
16^3 = (2^4)^3 = 2^12 = 4096
16^4 = (2^4)^4 = 2^16 = 65536
65536 [16^4] is too big for 41673, so we know that we will have only
four hex digits in our answer, from 16^3 down to 16^0.
Subtract each successive power of 16:
41673 minus 10 times 4096 [16^3] equals 41673 - 40960 = 713
713 minus 2 times 256 [16^2] equals 713 - 512 = 201
201 minus 12 times 16 [16^1] equals 201 - 192 = 9
9 minus 9 times 1 [16^0] equals 9 - 9 = 0 --> DONE
Step 3: Write down the powers of 16 as hexadecimal digits.
10 -> A times 16^3 A=10, B=11, C=12, D=13, E=14, F=15
2 -> 2 times 16^2
12 -> C times 16^1
9 -> 9 times 16^0
Step 4: Assemble the hex digits into a hexadecimal number, with the smallest
powers of 16 on the right and the biggest (most significant) on the left.
The number is positive/unsigned - no bit flipping is needed.
ANSWER: decimal 41673 converted to 16-bit unsigned hex is A2C9
EXAMPLE 3: Convert two's complement 20-bit hex A2C9 to decimal.
----------
Step 1: Check the sign. If negative, make it positive and save the sign.
A2C9h is actually 0A2C9h in hex, since we are told it is 20-bits wide.
Because the sign bit is off (since "0" = 0000 binary), this is a
positive 20-bit number. No need to flip any bits.
Step 2: multiply out the powers of 16 for each hex digit
0 times 16**4 = 0 times 65536 = 0
A times 16**3 = 10 times 4096 = 40960
2 times 16**2 = 2 times 256 = 512
C times 16**1 = 12 times 16 = 192
9 times 16**0 = 9 times 1 = 9
Add them all up and get TOTAL 41673
Step 3: put back the sign (saved from Step 1)
This is a positive number.
Answer 41673
EXAMPLE 4: Convert two's complement 16-bit hex 1A8C to decimal.
----------
Step 1: Number 1A8Ch is positive, since the leftmost hex digit "1" is
0001 binary and we can see that the left (sign) bit is zero.
Step 2: multiply out the powers of 16 for each hex digit
1 times 16**3 = 1 times 4096 = 4096
A times 16**2 = 10 times 256 = 2560
8 times 16**1 = 8 times 16 = 128
C times 16**0 = 13 times 1 = 13
Add them all up and get TOTAL 6796
Step 3: put back the sign (saved from Step 1)
This is a positive number.
Answer 6796
EXAMPLE 5: Convert two's complement 16-bit hex A123h to decimal.
----------
Step 1: Check the sign. If negative, make it positive and save the sign.
A123h is negative (the sign bit is on, since "A" = 1010 binary)
Use the table on A123 to flip the bits in each hex digit,
giving 5EDC which is the one's complement,
and then add one +1
giving 5EDD (a positive number, since "5" is 0101 binary)
Step 2: multiply out the powers of 16 for each hex digit
5 times 16**3 = 5 times 4096 = 20480
E times 16**2 = 14 times 256 = 3584
D times 16**1 = 13 times 16 = 208
D times 16**0 = 13 times 1 = 13
Add them all up and get 24285
Step 3: put back the sign (saved from Step 1)
Answer -24285 (negative)
EXAMPLE 6: Convert unsigned 16-bit hex A123 to decimal.
----------
Step 1: Unsigned numbers are all positive.
Step 2: multiply out the powers of 16 for each hex digit
A times 16**3 = 10 times 4096 = 40960
1 times 16**2 = 1 times 256 = 256
2 times 16**1 = 2 times 16 = 32
3 times 16**0 = 3 times 1 = 3
Add them all up and get 41251
Step 3: put back the sign (saved from Step 1)
Answer 41251
See Also
--------
Any Base Converter: Convert numbers in any base up to 32:
http://www.cut-the-knot.org/binary.shtml
--
| Ian! D. Allen - idallen@idallen.ca - Ottawa, Ontario, Canada
| Home Page: http://idallen.com/ Contact Improv: http://contactimprov.ca/
| College professor (Free/Libre GNU+Linux) at: http://teaching.idallen.com/
| Defend digital freedom: http://eff.org/ and have fun: http://fools.ca/