Re: portable way to get highest bit set?

David Brown <[email protected]> Wed, 11 Oct 2023 18:45:02 +0200
Newsgroups comp.lang.c,alt.comp.lang.c
Organization A noiseless patient Spider
Message-ID <[email protected]>
On 11/10/2023 18:19, candycanearter07 wrote:
> On 10/11/23 02:27, Anton Shepelev wrote:
>> candycanearter07:
>>
>>> What is the best/most portable way to get the highest bit
>>> set?
>>>
>>> ie. 011010001
>>> to  010000000
>>
>> What is your best attempt, even if unsuccessful?
>>
> 
> int out;
> for(out = 0x100000000; out; out >> 1)
>      if(out & input) break;
> 
> I'm trying to find something size independent, though.
> Or at least able to be swapped out with a #define

OK, that's a start.

First, I strongly recommend you use unsigned integer types for anything 
involving bit manipulation, masking, shifting, etc.  You avoid any 
awkwardness or potential undefined behaviour, and have the full range of 
the bits.  I also recommend using the C99 <stdint.h> size-specific 
types.  They are not quite as portable as the standard integer types, 
but they are portable enough for the vast majority of real-world cases, 
and you are always sure of the exact number of bits, which is often 
clearer IMHO.  (Note that not all C programmers will agree with my 
preferences here.)

Now, you still have not answered what you mean by "portable".  How I 
would approach this would depend significantly on that.  If "portable" 
meant "any target for gcc or clang", I'd be using gcc builtins.  If it 
meant "any C23 compiler", I'd likely use "auto" in my solution.  If it 
meant "any C11 or C17 compiler", I'd use "_Generic".  If it meant "any 
C99 compiler", I'd use <stdint.h> types.  If "portable" means any 
standard C version, with any hypothetical implementation, it's going to 
get messy putting together a solution that will work even for extended 
unsigned integer types that are bigger than "unsigned long".

These different approaches can have significantly different 
efficiencies, if that is important, but each has different requirements 
of the standard and compiler.