Author | Message | Time |
---|---|---|
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 |