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)