Valhalla Legends Forums Archive | General Programming | Hex-Binary Numeric Representation

AuthorMessageTime
Myndfyr
This was a post I made on GotDotNet in re: to someone who said that (s)he was getting strange results converting negative integers to hex format with the Int32.ToString("x") method. I thought it might be worthwhile as a reference here. :)

-----------

I'm not sure what you think is "strange" results for Hex. Here's how it works.

When a number is stored on a computer as a signed integer, it is stored 32-bits wide in what is called among electrical engineers a "Two's-Complement" number. That is, if you have (let's start in 8 bits) the number 42, that number can be broken down to 3 bits being on: 32, or 2^5, 8, or 2^3, and 2, or 2^1.

That is, 00101010b.

Within an 8-bit number, we have at most 256 different combinations. A byte, which is unsigned, will go from 0 (00000000b) to 255 (11111111b).

However, how do we represent non-positive integers with this notation?

We use the most-significant bit as a "sign bit" -- 1 for negative, 0 for positive. So, when you have the number 255 in an eight-bit number -- represented by 11111111b, if you were representing a signed number, you would have -1 (bear with me here -- I know that statement didn't make sense).

Let's follow this progression:

4: 00000100
3: 00000011
2: 00000010
1: 00000001
0: 00000000
-1: 11111111
-2: 11111110
-3: 11111101
-4: 11111100

The way that you convert between the positive representation and the negative representation in Two's Complement is by taking the bitwise-NOT of the values (effectively XOR-ing with 11111111b), and then adding 1 (binary). So, take the example of 4:

00000100
NOT it:
11111011
Add 1:
11111100

Try 1:
00000001
NOT it:
11111110
Add 1:
11111111

When you take the hex table into account:
0x0 = 0000b, 0x1 = 0001b, 0x2 = 0010b, 0x3 = 0011b
0x4 = 0100b, 0x5 = 0101b, 0x6 = 0110b, 0x7 = 0111b
0x8 = 1000b, 0x9 = 1001b, 0xa = 1010b, 0xb = 1011b,
0xc = 1100b, 0xd = 1101b, 0xe = 1110b, 0xf = 1111b

and use it to represent a binary number, you simply change them in groups of four:

so the number 42 (above), 00101010b, becomes:
0010 1010
2 a
0x2a

When you're taking the hex of a negative number, your sign bit will always be on, making the most significant digit _always_ at least 8. Take the number -8 for example:

positive 8:
00001000
negate:
11110111
add 1:
11111000
make hex:
f 8
0xf8

Hope that helps you understand the results you're getting!
April 23, 2004, 5:41 AM

Search