Re: portable way to get highest bit set?

jak <[email protected]> Thu, 12 Oct 2023 15:18:04 +0200
Newsgroups comp.lang.c,alt.comp.lang.c
Organization A noiseless patient Spider
Message-ID <[email protected]>
Michael S ha scritto:
> On Thu, 12 Oct 2023 13:35:01 +0200
> jak <[email protected]> wrote:
> 
>> Ben Bacarisse ha scritto:
>>> jak <[email protected]> writes:
>>>
>>>> Ben Bacarisse ha scritto:
>>>>> jak <[email protected]> writes:
>>>>>
>>>>>> candycanearter07 ha scritto:
>>>>>>> Hi,
>>>>>>> What is the best/most portable way to get the highest bit set?
>>>>>>> ie. 011010001
>>>>>>> to  010000000
>>>>>>
>>>>>> Hi,
>>>>>> I don't think it's the best but the most portable could be the
>>>>>> mathematical approach:
>>>>>>
>>>>>> #include <stdio.h>
>>>>>> #include <math.h>
>>>>>>
>>>>>> int main()
>>>>>> {
>>>>>>        unsigned long val = 3000, ret;
>>>>> Test case: val = 0xFFFFFFFFFFFFFFFF
>>>>
>>>> This is due to the approximation of the floating point:
>>>
>>> I know the reason.  I was just pointing out that you need to at
>>> least test the boundary cases!
>>>
>>
>> I am sure you knew and I have verified that the problem persists up to
>> "~0UL - 10000" but I don't find an elegant way, type independent, to
>> work around... just adding an 'if' or a ternary operator.
> 
> 
> I don't know what do you consider elegant, but that code solves
> problem of rounding:
> int save = fegetround();
> fesetround(FE_TOWARDZERO);
> volatile double dval = val;
> fesetround(save);
> Pay attention that without 'volatile' it is not guaranteed to work which
> I personally consider as a bug in the Standard.
> 
> Also frexp()/ldexp() would be a little less slow than yours log()/pow().
> int e;
> frexp(dval, &e);
> ldexp(0.5, e);
> But it still would not work at val=0.
> 
> I don't know what do you consider elegant, but that code solves
> problem of rounding:
> int save = fegetround();
> fesetround(FE_TOWARDZERO);
> volatile double dval = val;
> fesetround(save);
> Pay attention that without 'volatile' it is not guaranteed to work which
> I personally consider as a bug in the Standard.
> 
> Also frexp()/ldexp() would be a little less slow than yours log()/pow().
> int e;
> frexp(dval, &e);
> ldexp(0.5, e);
> But it still would not work at val=0.
> 
> I don't know what do you consider elegant, but that code solves
> problem of rounding:
> int save = fegetround();
> fesetround(FE_TOWARDZERO);
> volatile double dval = val;
> fesetround(save);
> Pay attention that without 'volatile' it is not guaranteed to work which
> I personally consider as a bug in the Standard.
> 
> Also frexp()/ldexp() would be a little less slow than yours log()/pow().
> int e;
> frexp(dval, &e);
> ldexp(0.5, e);
> But it still would not work at val=0.
> 
> 
Oops ... I was wrong branch. I hung the answer to the previous branch.
Excuse me. (jak: Thu, 12 Oct 2023 13:09:14 UTC)