Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <6143ebd-1bf-d88b-dbad-ae68ad169943@esi.com.au>
Date: Wed, 7 Aug 2024 10:51:24 +1000 (AEST)
From: Damian McGuckin <damianm@....com.au>
To: Markus Wichmann <nullplan@....net>
cc: musl@...ts.openwall.com
Subject: Re: Special cases in csinh and ctanh

On Tue, 6 Aug 2024, Markus Wichmann wrote:

> Am Wed, Aug 07, 2024 at 12:02:59AM +1000 schrieb Damian McGuckin:
>> I realise that 'y - y' creates a NaN when y is either an Infinity or NaN.
>> Won't that also raise an INVALID exception?
>>
>
> Yes it will.

That is what I assumed.

> As it should, since it calculates a new NaN where there
> wasn't one before (and, one layer up, csinh(0 + ? i) IS an invalid
> operation). y - y does NOT raise invalid if y already is QNaN.

That is what I assumed.

>> What does
>>
>> 	x * (y - y)
>>
>> achieve that y - y does not (in the above)
>
> The version in ctanh() sets the real part to 0 if x is zero, while the
> above always calculates NaN if y is not finite. Otherwise, the sign bit
> may be different, whatever information the sign bit of a NaN has.

Sorry, I was not clear enough.

Looking at the case where 'x' Is zero. It is effectively

ctanh:

   return CMPLX(x, y - y);

or

   return CMPLX(+0, qNaN); // if x is +0 && y == an infinity + raise INVALID
   return CMPLX(+0, qNaN); // if x is +0 && y == qNaN
   return CMPLX(-0, qNaN); // if x is -0 && y == an infinity + raise INVALID
   return CMPLX(-0, qNaN); // if x is -0 && y == qNaN

This is what I expect. It agrees with the standard. But

csinh:

   return CMPLX(copysign(0, x * (y - y), y - y);

or

   return CMPLX(??0, qNaN); // if y == an infinity + raise INVALID
   return CMPLX(??0, qNaN); // if y == qNaN

I put a double question mark in front of 0 because if I have no idea to 
what sign the expression x*(y-y) will evaluate.

I cannot see what all the extra effort buys because you end up with sort
of the same result. Actually the second result potentially could have the
a sign for the real part which violates the standard.

Similarly, for x non-zero, you get

ctanh:

   return CMPLX(y - y, y - y);

or

   return CMPLX(qNaN, qNAN); // if y is an infinity + raise INVALID
   return CMPLX(qNaN, qNAN); // if y is a qNAN

csinh:

   return CMPLX(y - y, x * (y - y));

or

   return CMPLX(qNaN, qNAN); // if y is an infinity + raise INVALID
   return CMPLX(qNaN, qNAN); // if y is a qNAN

Again, what does the multiplication get you except more complexity. I 
cannot see the reason using a multiplication for it. Or am I missing 
something because my brain is too busy watching the Olympics?

Thanks again - Damian

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.