public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Wilco Dijkstra <Wilco.Dijkstra@arm.com>
To: Paul Zimmermann <Paul.Zimmermann@inria.fr>
Cc: "libc-alpha@sourceware.org" <libc-alpha@sourceware.org>
Subject: Re: [PATCH 1/4] Add a routine for accurate reduction mod (2pi), for j0f/j1f/y0f/y1f.
Date: Tue, 9 Feb 2021 18:27:13 +0000	[thread overview]
Message-ID: <VE1PR08MB5599FC7E1122168C080A5148838E9@VE1PR08MB5599.eurprd08.prod.outlook.com> (raw)
In-Reply-To: <mweehpw6ag.fsf@tomate.loria.fr>

Hi Paul,

> reduce_fast is clearly not accurate enough: for x=0x1.96d666p+7, it gives
> y=0x1.947b0da22168cp+8 (and n=-128), and we clearly see that y is not in
> [-PI/4,PI/4] as advertized. What happens is that in the #else part of
> the code that is executed on my machine, r is larger than 2^31, thus the
> cast (int32_t) r overflows, the value of n is wrong, and thus the returned
> value x - n * p->hpi. Maybe a comment should be added about this limitation
> of reduce_fast?

Well the comment says:

/* Fast range reduction using single multiply-subtract.  Return the modulo of
   X as a value between -PI/4 and PI/4 and store the quadrant in NP.
   The values for PI/2 and 2/PI are accessed via P.  Since PI/2 as a double
   is accurate to 55 bits and the worst-case cancellation happens at 6 * PI/4,
   the result is accurate for |X| <= 120.0.  */

Ie. it won't be accurate enough over 120.0 (and yes, it will overflow at around
201 but that's well outside the allowed range). Note also reduce_large only
works for values larger than 2.0. The idea is that they complement each other,
allowing the common case to use the faster reduction - see eg. sinf:

  else if (__glibc_likely (abstop12 (y) < abstop12 (120.0f)))
      x = reduce_fast (x, p, &n);
  else if (abstop12 (y) < abstop12 (INFINITY))
      x = reduce_large (xi, &n);

We could add an inline helper that has this logic and the sign handling so
that it works as a generic range reducer across the full float range.
As Carlos points out, it's not essential for your patch, so it could be done
in another path.

There is a generic range reducer for double precision, however it is very
complex and slow, so it needs to be rewritten to use the reduce_fast algorithm.

> As for reduce_large, I need to run again the exhaustive tests for all four
> functions (j0, j1, y0, y1) and all four rounding modes to see if it is accurate
> enough.

It should be since it gives you x mod PI/4 with absolute error of about 2^-62.

Cheers,
Wilco

  reply	other threads:[~2021-02-09 18:27 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-09 11:35 Wilco Dijkstra
2021-02-09 13:30 ` Carlos O'Donell
2021-02-09 16:32 ` Paul Zimmermann
2021-02-09 18:27   ` Wilco Dijkstra [this message]
  -- strict thread matches above, loose matches on Subject: below --
2021-02-09  5:28 Paul Zimmermann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=VE1PR08MB5599FC7E1122168C080A5148838E9@VE1PR08MB5599.eurprd08.prod.outlook.com \
    --to=wilco.dijkstra@arm.com \
    --cc=Paul.Zimmermann@inria.fr \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).