unofficial mirror of libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Morten Welinder <mwelinder@gmail.com>
To: Alejandro Colomar <alx@kernel.org>
Cc: Vincent Lefevre <vincent@vinc17.net>,
	linux-man@vger.kernel.org,  libc-alpha@sourceware.org,
	jsm-csl@polyomino.org.uk, newbie-02@gmx.de
Subject: Re: Man page issues: logb, significand, cbrt, log2, log10, exp10
Date: Sun, 3 Mar 2024 17:26:46 -0500	[thread overview]
Message-ID: <CANv4PN=D-99oF86THKYFndZ5TQJ4oWga5n4DST4mhsLmq1Zr4A@mail.gmail.com> (raw)
In-Reply-To: <ZeRrRgEvvxjvHi-K@debian>

Sorry to be a bit of a pain.

Some testing says that the average error from exp10 is 300-500 times
bigger than the average error from pow(10,.). This is consistent
across a large range of arguments.

The maximum error from pow(10,.) in the samples is 1ulp (relative to a
reference rounded value, so the true error is likely less). The
maximum error from exp10 in the samples is 2ulp.

This is not surprising given that exp10 starts out by introducing a
rounding error due to the multiplication before the call to exp.

I didn't bother looking, but it is almost certainly true that there
are arguments for which exp10 is better than pow(10,.).  However, the
numbers below imply that such arguments are very rare compared to the
other way around.


-------------------------- average ----- max
Binade -7      exp10: 0.3378           1
Binade -7  pow(10,.): 0.0007           1
Binade -6      exp10: 0.3429           2
Binade -6  pow(10,.): 0.0007           1
Binade -5      exp10: 0.3532           2
Binade -5  pow(10,.): 0.0008           1
Binade -4      exp10: 0.3774           2
Binade -4  pow(10,.): 0.0008           1
Binade -3      exp10: 0.4402           2
Binade -3  pow(10,.): 0.0010           1
Binade -2      exp10: 0.4118           2
Binade -2  pow(10,.): 0.0009           1
Binade -1      exp10: 0.4228           2
Binade -1  pow(10,.): 0.0009           1
Binade  0      exp10: 0.4204           2
Binade  0  pow(10,.): 0.0009           1
Binade  1      exp10: 0.4221           2
Binade  1  pow(10,.): 0.0009           1
Binade  2      exp10: 0.4204           2
Binade  2  pow(10,.): 0.0009           1
Binade  3      exp10: 0.4222           2
Binade  3  pow(10,.): 0.0009           1
Binade  4      exp10: 0.4209           2
Binade  4  pow(10,.): 0.0009           1
Binade  5      exp10: 0.4200           2
Binade  5  pow(10,.): 0.0009           1
Binade  6      exp10: 0.4210           2
Binade  6  pow(10,.): 0.0009           1
Binade  7      exp10: 0.4210           2
Binade  7  pow(10,.): 0.0009           1

Notes:
1. Only positive arguments tested.
2. powl (long double version of pow) is used as a reference.  I
double-checked with a double-double version of pow (good to about
100ish bits) that this does not matter.




#define _GNU_SOURCE   1
#include <stdio.h>
#include <math.h>
#include <stdint.h>


static uint64_t
murmur64 (uint64_t h)
{
  h ^= h >> 33;
  h *= 0xff51afd7ed558ccdll;
  h ^= h >> 33;
  h *= 0xc4ceb9fe1a85ec53ll;
  h ^= h >> 33;
  return h;
}

static double
exp10ref (double x)
{
  volatile double y = (double)(powl (10.0l, x));
  return y;
}

static double
exp10viapow (double x)
{
  return pow (10, x);
}


static void
test_binade (int b, double (*f) (double), const char *funcname)
{
  uint64_t h = 0x0123456701234567ll;

  double ulps = 0;
  double mulp = 0;
  int N = 1000000;

  for (int i = 0; i < N; i++) {
    h = murmur64 (h);

    double x = ldexp ((h & 0xfffffffffffffll) | 0x10000000000000ll, b - 52);

    double y = f (x);
    double yref = exp10ref (x);
    double dy = fabs (y - yref);

    double ulp = dy / (nextafter (yref, INFINITY) - yref);
    ulps += ulp;
    if (ulp > mulp) mulp = ulp;
  }

  printf ("Binade %2d %10s: %6.4f  %10.0f\n",
      b, funcname, ulps / N, mulp);
}


int
main ()
{
  for (int b = -7; b <= 7; b++) {
    test_binade (b, exp10, "exp10");
    test_binade (b, exp10viapow, "pow(10,.)");
  }

  return 0;
}

  reply	other threads:[~2024-03-03 22:27 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CANv4PNkVv_0eLgiSP3L_KfC-eZJaVLZ5AP1AGfD0GNrR5M4Hrg@mail.gmail.com>
     [not found] ` <ZeEnJB96mMC5bfBz@debian>
     [not found]   ` <CANv4PNmMpiwfv5acr7U6VEVe7PE_AMTzkkpNoNN9jrtVzk_93Q@mail.gmail.com>
2024-03-02 21:54     ` Man page issues: logb, significand, cbrt, log2, log10, exp10 Alejandro Colomar
2024-03-03  2:02       ` Morten Welinder
2024-03-03  2:21         ` Alejandro Colomar
2024-03-03 11:46           ` Vincent Lefevre
2024-03-03 12:21             ` Alejandro Colomar
2024-03-03 22:26               ` Morten Welinder [this message]
2024-03-04 12:17         ` Adhemerval Zanella Netto
2024-03-05 16:12 ` [PATCH v2 0/3] manual/math.texi: logb(3) and cbrt(3) fixes Alejandro Colomar
2024-03-05 16:12   ` [PATCH v2 1/3] manual: logb(x) is floor(log2(fabs(x))) Alejandro Colomar
2024-03-29 22:08     ` DJ Delorie
2024-03-29 23:00       ` Alejandro Colomar
2024-03-05 16:12   ` [PATCH v2 2/3] manual: floor(log2(fabs(x))) has rounding errors Alejandro Colomar
2024-03-30  0:24     ` DJ Delorie
2024-03-30  9:27       ` Alejandro Colomar
2024-03-30  9:30         ` Alejandro Colomar
2024-03-30  9:47       ` Andreas Schwab
2024-03-05 16:12   ` [PATCH v2 3/3] manual: Cube roots are rarely representable Alejandro Colomar
2024-03-30  0:27     ` DJ Delorie
2024-03-30  7:07       ` Paul Zimmermann
2024-03-30 16:51         ` DJ Delorie
2024-03-30 18:42           ` Alejandro Colomar
2024-03-30 18:50             ` DJ Delorie
2024-03-30 19:07               ` Alejandro Colomar
2024-03-31 20:38   ` [PATCH v3 0/4] manual: arith.texi and math.texi fixes Alejandro Colomar
2024-03-31 20:38     ` [PATCH v3 1/4] manual: logb(x) is floor(log2(fabs(x))) Alejandro Colomar
2024-03-31 20:38     ` [PATCH v3 2/4] manual: floor(log2(fabs(x))) has rounding errors Alejandro Colomar
2024-03-31 20:38     ` [PATCH v3 3/4] manual: Clarify return value of cbrt(3) Alejandro Colomar
2024-04-01 18:57       ` DJ Delorie
2024-03-31 20:38     ` [PATCH v3 4/4] manual: significand() uses FLT_RADIX, not 2 Alejandro Colomar
2024-04-01 19:09       ` DJ Delorie
2024-03-04 15:29 Man page issues: logb, significand, cbrt, log2, log10, exp10 Wilco Dijkstra
2024-03-05  8:14 ` 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

  List information: https://www.gnu.org/software/libc/involved.html

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

  git send-email \
    --in-reply-to='CANv4PN=D-99oF86THKYFndZ5TQJ4oWga5n4DST4mhsLmq1Zr4A@mail.gmail.com' \
    --to=mwelinder@gmail.com \
    --cc=alx@kernel.org \
    --cc=jsm-csl@polyomino.org.uk \
    --cc=libc-alpha@sourceware.org \
    --cc=linux-man@vger.kernel.org \
    --cc=newbie-02@gmx.de \
    --cc=vincent@vinc17.net \
    /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).