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