I am working on a function that will essentially see which of two ints is larger. The parameters that are passed are 2 32-bit ints. The trick is the only operators allowed are ! ~ | & << >> ^ (no casting, other data types besides signed int, *, /, -, etc..).
My idea so far is to ^ the two binaries together to see all the positions of the 1 values that they don’t share. What I want to do is then take that value and isolate the 1 farthest to the left. Then see of which of them has that value in it. That value then will be the larger.
(Say we use 8-bit ints instead of 32-bit).
If the two values passed were 01011011 and 01101001
I used ^ on them to get 00100010.
I then want to make it 00100000 in other words 01xxxxxx -> 01000000
Then & it with the first number
!! the result and return it.
If it is 1, then the first # is larger.
Any thoughts on how to 01xxxxxx -> 01000000 or anything else to help?
Forgot to note: no ifs, whiles, fors etc…
Here’s a loop-free version which compares unsigned integers in O(lg b) operations where b is the word size of the machine. Note the OP states no other data types than
signed int, so it seems likely the top part of this answer does not meet the OP’s specifications. (Spoiler version as at the bottom.)Note that the behavior we want to capture is when the most significant bit mismatch is
1foraand0forb. Another way of thinking about this is any bit inabeing larger than the corresponding bit inbmeansais greater thanb, so long as there wasn’t an earlier bit inathat was less than the corresponding bit inb.To that end, we compute all the bits in
agreater than the corresponding bits inb, and likewise compute all the bits inaless than the corresponding bits inb. We now want to mask out all the ‘greater than’ bits that are below any ‘less than’ bits, so we take all the ‘less than’ bits and smear them all to the right making a mask: the most significant bit set all the way down to the least significant bit are now1.Now all we have to do is remove the ‘greater than’ bits set by using simple bit masking logic.
The resulting value is 0 if
a <= band nonzero ifa > b. If we want it to be1in the latter case we can do a similar smearing trick and just take a look at the least significant bit.Note: This should work for signed integers as well if you flip the top bit on both of the inputs, e.g.
a ^= 0x80000000.Spoiler
If you want an answer that meets all of the requirements (including 25 operators or less):
I’ll leave explaining why it works up to you.