Search code examples
javaintegerhexbit-manipulation

How to remove the nth hexadecimal digit of a integer number without using Strings?


Consider a hexadecimal integer value such as n = 0x12345, how to get 0x1235 as result by doing remove(n, 3) (big endian)?

For the inputs above I think this can be achieved by performing some bitwising steps:

  • partA = extract the part from index 0 to targetIndex - 1 (should return 0x123);
  • partB = extract the part from targetIndex + 1 to length(value) - 1 (0x5);
  • result, then, can be expressed by ((partA << length(partB) | partB), giving the 0x1235 result.

However I'm still confused in how to implement it, once each hex digit occupies 4 spaces. Also, I don't know a good way to retrieve the length of the numbers.

This can be easily done with strings however I need to use this in a context of thousands of iterations and don't think Strings is a good idea to choose.

So, what is a good way to this removing without Strings?


Solution

  • Similar to the idea you describe, this can be done by creating a mask for both the upper and the lower part, shifting the upper part, and then reassembling.

    int remove(int x, int i) {
        // create a mask covering the highest 1-bit and all lower bits
        int m = x;
        m |= (m >>> 1);
        m |= (m >>> 2);
        m |= (m >>> 4);
        m |= (m >>> 8);
        m |= (m >>> 16);
        // clamp to 4-bit boundary
        int l = m & 0x11111110;
        m = l - (l >>> 4);
        // shift to select relevant position
        m >>>= 4 * i;
        // assemble result
        return ((x & ~(m << 4)) >>> 4) | (x & m);
    }
    

    where ">>>" is an unsigned shift.

    As a note, if 0 indicates the highest hex digit in a 32-bit word independent of the input, this is much simpler:

    int remove(int x, int i) {
        int m = 0xffffffff >>> (4*i);
        return ((x & ~m) >>> 4) | (x & (m >>> 4));
    }