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