Implementing C99's roundf(), round(), and roundl()

David Schultz das at FreeBSD.ORG
Mon Dec 1 00:54:29 PST 2003


On Mon, Dec 01, 2003, Bruce Evans wrote:
> And we really shouldn't do arithmetic on the NaNs.  ceilf() should return
> its arg for a NaN, but it's not clear what happens for -x.  Well, I checked
> what happens starting with the QNaN x= 0.0 / 0.0.  Almost everything is
> broken:
> - gcc miscomputes 0.0 / 0.0 at compile time.  It gives a positive NaN, but
>   the npx would give a negative NaN ("Real Indefinite" = the same one except
>   with the opposite sign).
> - gcc invalidly optimizes -x by ORing in the sign bit (even without -O).
>   It should do the same as the npx (which is to not change anything).
> - printf() doesn't print the sign bit for NaNs.
> - C99 requires printf() to misspell "NaN" as "nan"

I thought about that, but I didn't know that the distinction
between positive and negative NaN mattered to anyone.  If you
ignore these distinctions, then any amount of arithmetic on a NaN
does nothing, save the possibility of raising an exception.

In this case, swapping the sense of the 'if' ought to fix the
problem, although an isnan() check could be added instead to be on
the safe side.

> All the other corner cases need to be checked.  It's possibly to check
> all 2^32 cases for floats (once you know the correct results).

If I had a better way to compute the correct results, I'd commit
that instead.  ;-P  (Okay, actually, I could just use the npx.)

> Other things to check: setting of exception flags.  I'm not sure if the
> settings by ceil() are the right ones and the only ones.

What little POSIX says about flags seems to be identical for
ceil() and round().


More information about the freebsd-standards mailing list