To use the approach detailed below, there must be a force of 2. This should not be otherwise.
The general approach looks like this: "if (index> = size) {index = size - index;}" (size 10, index 10, the resulting index is 0). It is slower and error prone regarding the following approach.
Using the power of the two, we can use the following:
size = 32 bin(size) => '00100000' mask = size - 1; bin(mask) => '00011111'
Applying this mask with bitwise and we can only select bits that contain numbers in the range from 0 to 31 when the index grows:
index = 4 bin(4 & mask) => '00000100' (4) # index 32 wraps. note here that we do no bounds checking, # no manipulation of the index is necessary. we can simply # and safely use the result. index = 32 bin(index & mask) => '00000000' (0) index = 33 bin(index & mask) => '00000001' (1) index = 64 bin(index & mask) => '00000000' (0) index = 65 bin(index & mask) => '00000001' (1)
This approach does not require any comparisons, no branches, and is not safe (the resulting index is always within the bounds). This has the added advantage of not smashing information; while index 65 refers to element 1, I still retain information that the index is logically 65 (which turns out to be quite useful).
I would also like to add that it is as effective when the index grows to 3456237 (address 13 in the buffer), as when it is 3.
I know I'm late for the party, I'm not even sure how I found this question :-) Hope this helps.
source share