From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.3 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL autolearn=ham autolearn_force=no version=3.4.4 Received: from second.openwall.net (second.openwall.net [193.110.157.125]) by inbox.vuxu.org (Postfix) with SMTP id A2249239E1 for ; Wed, 7 Aug 2024 02:51:40 +0200 (CEST) Received: (qmail 30189 invoked by uid 550); 7 Aug 2024 00:51:34 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Reply-To: musl@lists.openwall.com Received: (qmail 30154 invoked from network); 7 Aug 2024 00:51:34 -0000 Date: Wed, 7 Aug 2024 10:51:24 +1000 (AEST) From: Damian McGuckin To: Markus Wichmann cc: musl@lists.openwall.com In-Reply-To: Message-ID: <6143ebd-1bf-d88b-dbad-ae68ad169943@esi.com.au> References: MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset=US-ASCII Subject: Re: [musl] 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