Re: portable way to get highest bit set?
Michael S <[email protected]> Thu, 12 Oct 2023 15:36:57 +0300
| Newsgroups | comp.lang.c,alt.comp.lang.c |
|---|---|
| Organization | A noiseless patient Spider |
| Message-ID | <[email protected]> |
On Thu, 12 Oct 2023 13:35:01 +0200 jak <[email protected]> wrote: > Ben Bacarisse ha scritto: > > jak <[email protected]> writes: > >=20 > >> 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=A0 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 =3D 3000, ret; > >>> Test case: val =3D 0xFFFFFFFFFFFFFFFF > >> > >> This is due to the approximation of the floating point: > >=20 > > I know the reason. I was just pointing out that you need to at > > least test the boundary cases! > >=20 >=20 > 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 =3D fegetround(); fesetround(FE_TOWARDZERO); volatile double dval =3D 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=3D0.=20 I don't know what do you consider elegant, but that code solves problem of rounding: int save =3D fegetround(); fesetround(FE_TOWARDZERO); volatile double dval =3D 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=3D0.=20 I don't know what do you consider elegant, but that code solves problem of rounding: int save =3D fegetround(); fesetround(FE_TOWARDZERO); volatile double dval =3D 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=3D0.=20