I am having a difficult time figuring out how to translate hexadecimal byte code in to decimal using two's complement when the number is negative. For example: if the number is 0xF99 (which is 1111 1001 1001 in binary), then do you proceed using two's complement indicated by the binary code? For instance, do you start with -2048 and then add 1024 and so on to get the answer in decimal?
-
$\begingroup$ Is this a negative number ? Usually hex numbers have an even number of digits, and yours could be 0x0F99 instead. If not, subtract 0x1000, which is 4096. $\endgroup$ – Yves Daoust Mar 9 '17 at 10:07
"For instance, do you start with -2048 and then add 1024 and so on to get the answer in decimal?"
Yep, that'll do it!
Another way is to use the formula $-x = NOT(x-1)$ (or $-x = NOT(x) + 1$). Then you can just compute it as if it were a positive number.
There are (at least) three ways, but in both cases you have to know the bit width of the two complement. For this to be meaningful I would assume that we have 12 bits (otherwise the number would be positive)
The "computer" way is to bitwise invert the number and add $1$ and then negate it. In your example the bitwise inverse of $(F99)_{16}$ is $(066)_{16}$ (you can check by going via binary if you wish, but there's a trick to do this directly). Then convert that to decimal and you get $102$, add $1$ and you get $103$ so the result is the negation $-133$ of this.
The "mathematical" way is to convert it to decimal and then subtract $2^n$ where $n$ is the number of bits. $(F99)_{16}$ is $3993$ and $2^{12} = 4096$. Then subtracting you get $3993-4096=-103$.
The "direct conversion" way. Here we use how the two complement wraps at $(800\cdots)_{16}$. We convert to decimal in the normal way except we interpret the most significant hexit accordingly. Instead of having $8$ in this position denote $+8$ we let it denote $-8$ (and similarily $9$ denotes $-7$ and so on and finally $F$ denotes $-1$). This way we get $(-1)16^2 + 9 16^1 + 9 = -103$
(The trick to logically invert hexadecimal directly is to use that each hexit corresponds to four bits and you can either use a table for inversion of hexits or use the fact that inversion of a four bit number is the same as subtracting it from $15$).
Positive numbers run from 0x000
(0
) to 0x7FF
(2047
). The next numbers are 0x800
(unsigned 2048
, signed -2048
) up to 0xFFF
(unsigned 4095
, signed -1
).
The adjustment is by subtracting 0x1000
(4096
).