Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 4 Mar 2012 13:43:39 -0500
From: Rich Felker <>
Subject: Re: libm

On Sun, Mar 04, 2012 at 03:50:41PM +0100, Szabolcs Nagy wrote:
> > - Why are there two versions (one "slow") of rem_pio2?
> > 
> originally code they are __ieee754_rem_pio2 and __kernel_rem_pio2
> maybe slow is not the best name
> the slow version is only called (by the non-slow one)
> for large numbers (>2^20) when multi precision arithmetic
> is needed using many bits of 2/pi
> (there is a large ipio2 array in that file)

Yes, that left me rather confused. The original names are confusing
too. In both cases it sounds like you have 2 versions of the same code
(fast/slow or different conformance profiles) rather than 2 different

> maybe it should be called __rem_pio2_large ?

That's better. Not sure what the best name would be..

> > gcc-specific hacks involving __typeof__. If gcc4 allows _Generic even
> > with -std=c99 etc. then I think _Generic is the best.
> > 
> no, gcc does not support it
> (i have a gcc 4.7 built from svn in october and it has -std=c1x,
> but _Generic is not supported)
> i wrote it using generic since i couldnt come up with
> any way to solve it in c99

There's no way to solve it in C99 matching the return types, but if
you don't care about return types, it's pretty easy (albeit ugly and
verbose) with ?: conditionals based on sizeof(x).

Since gcc still doesn't support _Generic, I think it might be
preferable to use the old approach (sizeof tests) and add (with a
conditionally defined macro) a cast to __typeof__((x)+1.0f) (or
__typeof__((x)+(y)+1.0f), etc. as needed) on the result that's only
enabled when __GNUC__ is defined. Then the fallback case would fail to
have the right result types, but at least the right functions would
get called.

> > > i wonder if it's ok to use a polyeval(coeffs, x) function instead
> > > of writing out the polynomial (some openbsd long double code uses
> > > such thing but not everywhere)
> > 
> > I suspect the functions that aren't using it right now depend on a
> > particular evaluation order to avoid loss of precision. I could be
> > wrong though; that's just my best guess.
> > 
> it's just a minor detail, but this was one of the parts where
> things could be a bit nicer and more consistent (probably)
> (coeffs in array, and using some static inline eval etc,
> it might not be a good idea for some technical reason,
> but i dont yet see why)

If it's not going to change the behavior of the code and it's just a
matter of inlining/un-inlining, I'm fairly indifferent to how you want
to do it.

> > > todo:
> > > - move the code to musl tree so the changes are recorded there
> > 
> > Very interested in doing this sooner rather than later.
> > 
> ok
> complex is missing but it is not hard to add
> (if you want to wait for it)

Either way.

> the parts i wrote may need some review or testing
> (it can be done after merging of course)

Yes, I'm okay with that.

> (it would be nice if musl had a dedicated testing
> package where one could add test functions
> and easy to run)

There's the libc-testsuite git repo, and then cluts. Neither is
musl-specific. The former is much broader in scope; the latter is
probably more intensive in the few areas it tests.

> ok so using compound literal
> i was thinking about this
> something like this will work


> the difficult part is figuring out if it can be used internally
> (many math functions start by turning the float/double
> into unsigned int, then doing various checks to handle
> special cases like nan, inf, signbit, etc using bithacks
> i thought most of them could be isnan() etc
> eg compare the current fmax to the freebsd one
> i'm not sure if this can be done in general
> because some bit hacks will be needed anyway
> and it might be better doing the conversion
> once

Yes, at least it would be a major undertaking to convert all the code
and ensure that no bugs are introduced. I think it's fine leaving it
how it is for now. I still want the fast isnan, etc. for applications
to use, though (and for use by other parts of libc like printf).

> many functions do checks like
>   if(x < 12.34) ... else if(x < 78.9) ...
> but using unsigned int arithmetics like
>   if ((x&bitmask) < 0xabcdef) ...
> which is not clear, but i guess this
> cannot be changed because float compare
> does a different thing
> but it would be nice to reduce the bithacks
> without changing the semantics or performance)

The semantics should only be changed if the goal is to consider
NAN/INF as "large" values too. Of course you also get abs() for free
using the representation and bitmask. Otherwise, for finite
comparisons comparing the representations and comparing the
floating-point values should have the same behavior.


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.