NetBSD-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: NetBSD math asinf() Issue



Hi,

2009/9/18 Woodchuck <marmot%pennswoods.net@localhost>:
>> The code seems to be DTRT'ing. it runs 'return (x-x)/(x-x);' but ends up with
>> 0. I did not see anything wrong in the assembly code either. Strange.
>>
>> christos
>
> sorry, I have only an OpenBSD source tree (v 4.2) available.  In the source 
> for
> libm, there are two asinf routines, in w_asinf.c and e_asinf.c  w_* are 
> wrappers
> for ieee routines in e_*.   In the case of asinf(|x|>1), e_asinf.c
> returns as you
> say, (x-x)/(x-x), which should be NaN.  The wrapper in w_asinf.c, however,
> munges this value,  quote:
>
> /usr/src/lib/libm/src/w_asinf.c
>
> float
> asinf(float x)          /* wrapper asinf */
> {
> #ifdef _IEEE_LIBM
>        return __ieee754_asinf(x);
> #else
>        float z;
>        z = __ieee754_asinf(x);
>        if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z;
>        if(fabsf(x)>(float)1.0) {
>            /* asinf(|x|>1) */
>            return (float)__kernel_standard((double)x,(double)x,102);
>        } else
>            return z;
> #endif
> }
>
> in the usual case, it would return __kernel_standard stuff:  quote:
>
> /usr/src/lib/libm/src/k_standard.c
>
>  case 102:
>                /* asin(|x|>1) */
>                exc.type = DOMAIN;
>                exc.name = type < 100 ? "asin" : "asinf";
>                exc.retval = zero;
>                if(_LIB_VERSION == _POSIX_)
>                  errno = EDOM;
>                else if (!matherr(&exc)) {
>                  if(_LIB_VERSION == _SVID_) {
>                        (void) WRITE2("asin: DOMAIN error\n", 19);
>                  }
>                  errno = EDOM;
>                }
>                break;
>
> __kernel_standard_... returns exc.retval, here set to zero.
>
> I assume that NetBSD uses a similar (or the same) scheme in libmath.
>
> Dave
> --
> Caution, this account is hosted by gmail.
> Strangers scan the content of all mail transiting such accounts.

Yes, in the NetBSD implementation if asinf(x) where x > 1 the function
__kernel_standard is called which fills the return value as zero as
below:

$ cat lib/libm/src/k_standard.c
:
:
            case 102:
                /* asin(|x|>1) */
                exc.type = DOMAIN;
                exc.name = type < 100 ? "asin" : "asinf";
                exc.retval = zero;                             <------- HERE
                if(_LIB_VERSION == _POSIX_)
                  errno = EDOM;
                else if (!matherr(&exc)) {
                  if(_LIB_VERSION == _SVID_) {
                        (void) WRITE2("asin: DOMAIN error\n", 19);
                  }
                  errno = EDOM;
                }
                break;
:
:

As mentioned in the label 'HERE'

The behavior for sinf() is by specification i.e implementation defined.
In GNU C libraries NAN is returned.

I am not sure if this is the correct behavior expected by applications.

Let me know your views on this.

Thanks & Regards,
Channa


Home | Main Index | Thread Index | Old Index