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 index0
totargetIndex - 1
(should return0x123
);partB
= extract the part fromtargetIndex + 1
tolength(value) - 1
(0x5
);- result, then, can be expressed by
((partA << length(partB) | partB)
, giving the0x1235
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?
Advertisement
Answer
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)); }