NetBSD-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: NetBSD math asinf() Issue
> I am using math library from NetBSD libraries.
> I faced some issue while using the API asinf().
> asinf() does not return proper values for some inputs
>
> The following is the test code to reproduce the issue:
Below I've modified your test program:
------------------------------ snip
#include <math.h>
#include <float.h>
#include <stdio.h>
#include <stdint.h>
#ifndef NAN
#define NAN (0.0f/0.0f)
#endif
#ifndef INF
#define INF (1.0f/0.0f)
#endif
int main()
{
float result = asinf(0x1.fffffep+127F);
float expected = NAN;
/*
* Result is expected to be NAN for the above
* input
*/
printf("POSIX / default:\n");
printf("Returned :%.8eF, expected: %.8eF\n", result, expected);
_LIB_VERSION = _IEEE_;
printf("IEEE:\n");
result = asinf(0x1.fffffep+127F);
printf("Returned :%.8eF, expected: %.8eF\n", result, expected);
return 0;
}
------------------------------ snip
and with it I get
POSIX / default:
Returned :0.00000000e+00F, expected: nanF
IEEE:
Returned :nanF, expected: nanF
Now...
By default, the build of lib/libm/ builds what is there called a
"multi-standard runtime math library", meaning that the actual
semantics can be changed at run-time. The comments in
lib/libm/Makefile say:
# Here is how to set up CPPFLAGS to create the desired libm at
# compile time:
#
# CPPFLAGS = -D_IEEE_LIBM ... IEEE libm (recommended)
# CPPFLAGS = -D_SVID3_MODE ... Multi-standard supported
# libm with SVID as the
# default standard
# CPPFLAGS = -D_XOPEN_MODE ... Multi-standard supported
# libm with XOPEN as the
# default standard
# CPPFLAGS = -D_POSIX_MODE ... Multi-standard supported
# libm with POSIX as the
# default standard
# CPPFLAGS = ... Multi-standard supported
# libm with IEEE as the
# default standard
Now, it appears that unless you're building for vax, CPPFLAGS
gets -D_MULTI_LIBM -D_POSIX_MODE added to it, ref:
.if (${MACHINE_ARCH} != "vax")
CPPFLAGS+= -D_MULTI_LIBM -D_POSIX_MODE
lib/libm/src/s_lib_version.c then defaults _LIB_VERSION to _POSIX_.
As has been observed elsewhere in this thread, in the multi-
standard library case, each math function is handled by a wrapper
which does certain adjustments to the results, partly dependent
on which standard is selected for the library.
The web page documenting asinf(), at
http://www.opengroup.org/onlinepubs/009695399/functions/asinf.html
clearly defers to the ISO C standard to define the actual
semantics, quoting:
The functionality described on this reference page is aligned
with the ISO C standard. Any conflict between the requirements
described here and the ISO C standard is unintentional. This
volume of IEEE Std 1003.1-2001 defers to the ISO C standard.
...and I seem to recall that the ISO C standard, the latest
available draft at
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
Annex F (floating point) says that this is basically previously
designated ANSI/IEEE 754â1985. This is most probably what is
referred to as "IEEE" in our math library.
For asinf(), ISO C says:
asin(x) returns a NaN and raises the "invalid" floating-point
exception for abs(x) > 1.
Now, the POSIX / opengroup.org page above said that
...either a NaN (if supported), or an implementation-defined
value shall be returned.
Most of the CPUs NetBSD runs on support NaNs, so in that case I
don't see that we have much of a choice in the matter if we want
to comply to the standard.
What I don't understand is this:
1) Why our math library is set up to provide non-IEEE semantics
by default, so that a user has to insert the above kludge into
his program to get the IEEE semantics.
2) Why the POSIX behaviour deviates from the IEEE semantics,
since the standard appears to imply they should have the same
semantics.
It may be that earlier versions of the POSIX standard dictated
other behaviour, perhaps?
Best regards,
- HÃvard
Home |
Main Index |
Thread Index |
Old Index