Search code examples
cwindowsassembly64-bit

Efficient Conversion of a Binary Number to Hexadecimal String


I am writing a program that converts a binary value's hexadecimal representation to a regular string. So each character in the hex representation would convert to two hexadecimal characters in the string. This means the result will be twice the size; a hexadecimal representation of 1 byte would need two bytes in a string.

Hexadecimal Characters

0123456789                    ;0x30 - 0x39
ABCDEF                        ;0x41 - 0x46

Example

0xF05C1E3A                    ;hex
4032568890                    ;dec

would become

0x4630354331453341            ;hex
5057600944242766657           ;dec

Question?

Are there any elegant/alternative(/interesting) methods for converting between these states, other than a lookup table, (bitwise operations, shifts, modulo, etc)? I'm not looking for a function in a library, but rather how one would/should be implemented. Any ideas?


Solution

  • Here's a solution with nothing but shifts, and/or, and add/subtract. No loops either.

    uint64_t x, m;
    x = 0xF05C1E3A;
    x = ((x & 0x00000000ffff0000LL) << 16) | (x & 0x000000000000ffffLL);
    x = ((x & 0x0000ff000000ff00LL) << 8)  | (x & 0x000000ff000000ffLL);
    x = ((x & 0x00f000f000f000f0LL) << 4)  | (x & 0x000f000f000f000fLL);
    x += 0x0606060606060606LL;
    m = ((x & 0x1010101010101010LL) >> 4) + 0x7f7f7f7f7f7f7f7fLL;
    x += (m & 0x2a2a2a2a2a2a2a2aLL) | (~m & 0x3131313131313131LL);
    

    Above is the simplified version I came up with after a little time to reflect. Below is the original answer.

    uint64_t x, m;
    x = 0xF05C1E3A;
    x = ((x & 0x00000000ffff0000LL) << 16) | (x & 0x000000000000ffffLL);
    x = ((x & 0x0000ff000000ff00LL) << 8) | (x & 0x000000ff000000ffLL);
    x = ((x & 0x00f000f000f000f0LL) << 4) | (x & 0x000f000f000f000fLL);
    x += 0x3636363636363636LL;
    m = (x & 0x4040404040404040LL) >> 6;
    x += m;
    m = m ^ 0x0101010101010101LL;
    x -= (m << 2) | (m << 1);
    

    See it in action: http://ideone.com/nMhJ2q