public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] manual: logb(x) is floor(log2(fabs(x)))
       [not found] <ZeZIVzJ_Wl42SnF2@debian>
@ 2024-03-04 22:40 ` Alejandro Colomar
  2024-03-05 10:02   ` Vincent Lefevre
  0 siblings, 1 reply; 7+ messages in thread
From: Alejandro Colomar @ 2024-03-04 22:40 UTC (permalink / raw)
  To: libc-alpha; +Cc: Alejandro Colomar, Morten Welinder, Adhemerval Zanella Netto

[-- Attachment #1: Type: text/plain, Size: 1090 bytes --]

log2(3) doesn't accept negative input, but it seems logb(3) does accept
it.

Link: <https://lore.kernel.org/linux-man/ZeYKUOKYS7G90SaV@debian/T/#u>
Reported-by: Morten Welinder <mwelinder@gmail.com>
Cc: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
---
 manual/math.texi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/manual/math.texi b/manual/math.texi
index 2f6ee253b9..bf4027c4ee 100644
--- a/manual/math.texi
+++ b/manual/math.texi
@@ -561,7 +561,7 @@ These functions return the base-2 logarithm of @var{x}.
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
 These functions extract the exponent of @var{x} and return it as a
 floating-point value.  If @code{FLT_RADIX} is two, @code{logb} is equal
-to @code{floor (log2 (x))}, except it's probably faster.
+to @code{floor (log2 (fabs ((x)))}, except it's probably faster.
 
 If @var{x} is de-normalized, @code{logb} returns the exponent @var{x}
 would have if it were normalized.  If @var{x} is infinity (positive or
-- 
2.43.0


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] manual: logb(x) is floor(log2(fabs(x)))
  2024-03-04 22:40 ` [PATCH] manual: logb(x) is floor(log2(fabs(x))) Alejandro Colomar
@ 2024-03-05 10:02   ` Vincent Lefevre
  2024-03-05 11:10     ` Alejandro Colomar
  2024-03-05 13:16     ` Morten Welinder
  0 siblings, 2 replies; 7+ messages in thread
From: Vincent Lefevre @ 2024-03-05 10:02 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: libc-alpha, Morten Welinder, Adhemerval Zanella Netto

On 2024-03-04 23:40:59 +0100, Alejandro Colomar wrote:
> log2(3) doesn't accept negative input, but it seems logb(3) does
> accept it.

Yes, but unrelated to that, there was an issue with the text before.

> Link: <https://lore.kernel.org/linux-man/ZeYKUOKYS7G90SaV@debian/T/#u>
> Reported-by: Morten Welinder <mwelinder@gmail.com>
> Cc: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
> Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
>  manual/math.texi | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/manual/math.texi b/manual/math.texi
> index 2f6ee253b9..bf4027c4ee 100644
> --- a/manual/math.texi
> +++ b/manual/math.texi
> @@ -561,7 +561,7 @@ These functions return the base-2 logarithm of @var{x}.
>  @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
>  These functions extract the exponent of @var{x} and return it as a
>  floating-point value.  If @code{FLT_RADIX} is two, @code{logb} is equal
> -to @code{floor (log2 (x))}, except it's probably faster.
> +to @code{floor (log2 (fabs ((x)))}, except it's probably faster.

No, it isn't necessarily equal. The code floor (log2 (fabs ((x)))
can give an incorrect result due to rounding if x is just before
a power of 2, in particular if x is large.

#include <stdio.h>
#include <float.h>
#include <math.h>

int main (void)
{
  double x = DBL_MAX;

  printf ("x = %a\n", x);
  printf ("%a\n", log2 (fabs (x)));
  printf ("%a\n", floor (log2 (fabs (x))));
  printf ("%a\n", logb (x));
  return 0;
}

outputs

x = 0x1.fffffffffffffp+1023
0x1p+10
0x1p+10
0x1.ff8p+9

on an x86_64 machine.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] manual: logb(x) is floor(log2(fabs(x)))
  2024-03-05 10:02   ` Vincent Lefevre
@ 2024-03-05 11:10     ` Alejandro Colomar
  2024-03-05 11:37       ` Vincent Lefevre
  2024-03-05 13:16     ` Morten Welinder
  1 sibling, 1 reply; 7+ messages in thread
From: Alejandro Colomar @ 2024-03-05 11:10 UTC (permalink / raw)
  To: Vincent Lefevre, libc-alpha, Morten Welinder, Adhemerval Zanella Netto

[-- Attachment #1: Type: text/plain, Size: 1709 bytes --]

Hi Vincent!

On Tue, Mar 05, 2024 at 11:02:51AM +0100, Vincent Lefevre wrote:
> On 2024-03-04 23:40:59 +0100, Alejandro Colomar wrote:
> > log2(3) doesn't accept negative input, but it seems logb(3) does
> > accept it.
> 
> Yes, but unrelated to that, there was an issue with the text before.
> 
> > Link: <https://lore.kernel.org/linux-man/ZeYKUOKYS7G90SaV@debian/T/#u>
> > Reported-by: Morten Welinder <mwelinder@gmail.com>
> > Cc: Adhemerval Zanella Netto <adhemerval.zanella@linaro.org>
> > Signed-off-by: Alejandro Colomar <alx@kernel.org>
> > ---
> >  manual/math.texi | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/manual/math.texi b/manual/math.texi
> > index 2f6ee253b9..bf4027c4ee 100644
> > --- a/manual/math.texi
> > +++ b/manual/math.texi
> > @@ -561,7 +561,7 @@ These functions return the base-2 logarithm of @var{x}.
> >  @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
> >  These functions extract the exponent of @var{x} and return it as a
> >  floating-point value.  If @code{FLT_RADIX} is two, @code{logb} is equal
> > -to @code{floor (log2 (x))}, except it's probably faster.
> > +to @code{floor (log2 (fabs ((x)))}, except it's probably faster.
> 
> No, it isn't necessarily equal. The code floor (log2 (fabs ((x)))
> can give an incorrect result due to rounding if x is just before
> a power of 2, in particular if x is large.

Hmmm, the bug is different, so how about a second patch for fixing that?

For that, I'd do s/equal/similar/ and s/faster/more accurate/.  Does it
sound good to you?

Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>
Looking for a remote C programming job at the moment.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] manual: logb(x) is floor(log2(fabs(x)))
  2024-03-05 11:10     ` Alejandro Colomar
@ 2024-03-05 11:37       ` Vincent Lefevre
  2024-03-05 12:30         ` Alejandro Colomar
  0 siblings, 1 reply; 7+ messages in thread
From: Vincent Lefevre @ 2024-03-05 11:37 UTC (permalink / raw)
  To: Alejandro Colomar; +Cc: libc-alpha, Morten Welinder, Adhemerval Zanella Netto

On 2024-03-05 12:10:23 +0100, Alejandro Colomar wrote:
> Hi Vincent!
> 
> On Tue, Mar 05, 2024 at 11:02:51AM +0100, Vincent Lefevre wrote:
> > On 2024-03-04 23:40:59 +0100, Alejandro Colomar wrote:
> > > diff --git a/manual/math.texi b/manual/math.texi
> > > index 2f6ee253b9..bf4027c4ee 100644
> > > --- a/manual/math.texi
> > > +++ b/manual/math.texi
> > > @@ -561,7 +561,7 @@ These functions return the base-2 logarithm of @var{x}.
> > >  @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
> > >  These functions extract the exponent of @var{x} and return it as a
> > >  floating-point value.  If @code{FLT_RADIX} is two, @code{logb} is equal
> > > -to @code{floor (log2 (x))}, except it's probably faster.
> > > +to @code{floor (log2 (fabs ((x)))}, except it's probably faster.

BTW, note that there is a missing closing parenthesis, or actually,
an opening parenthesis that could be removed, i.e.

  @code{floor (log2 (fabs (x)))}

> > No, it isn't necessarily equal. The code floor (log2 (fabs ((x)))
> > can give an incorrect result due to rounding if x is just before
> > a power of 2, in particular if x is large.
> 
> Hmmm, the bug is different, so how about a second patch for fixing that?

Yes.

> For that, I'd do s/equal/similar/ and s/faster/more accurate/.  Does it
> sound good to you?

I think that "more accurate" is misleading because this is actually
much more than "more accurate": logb is guaranteed to give the exact
result (the result is a small integer, thus exactly representable),
while floor (log2 (fabs (x))) may give an incorrect integer (there is
a small inaccuracy up to log2, but this becomes a much more important
problem due to the fact that floor is mathematically a discontinuous
function).

I would suggest:

@code{logb} is similar to @code{floor (log2 (fabs (x)))}, except that
the latter code may give an incorrect integer.

If needed, one can add an explanation: "due to intermediate rounding";
or an example: ", e.g. on DBL_MAX".

Regards,

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] manual: logb(x) is floor(log2(fabs(x)))
  2024-03-05 11:37       ` Vincent Lefevre
@ 2024-03-05 12:30         ` Alejandro Colomar
  0 siblings, 0 replies; 7+ messages in thread
From: Alejandro Colomar @ 2024-03-05 12:30 UTC (permalink / raw)
  To: Vincent Lefevre, libc-alpha, Morten Welinder, Adhemerval Zanella Netto

[-- Attachment #1: Type: text/plain, Size: 1423 bytes --]

Hi Vincent,

On Tue, Mar 05, 2024 at 12:37:38PM +0100, Vincent Lefevre wrote:
> > > > -to @code{floor (log2 (x))}, except it's probably faster.
> > > > +to @code{floor (log2 (fabs ((x)))}, except it's probably faster.
> 
> BTW, note that there is a missing closing parenthesis, or actually,
> an opening parenthesis that could be removed, i.e.
> 
>   @code{floor (log2 (fabs (x)))}

Oops!


> > For that, I'd do s/equal/similar/ and s/faster/more accurate/.  Does it
> > sound good to you?
> 
> I think that "more accurate" is misleading because this is actually
> much more than "more accurate": logb is guaranteed to give the exact
> result (the result is a small integer, thus exactly representable),
> while floor (log2 (fabs (x))) may give an incorrect integer (there is
> a small inaccuracy up to log2, but this becomes a much more important
> problem due to the fact that floor is mathematically a discontinuous
> function).
> 
> I would suggest:
> 
> @code{logb} is similar to @code{floor (log2 (fabs (x)))}, except that
> the latter code may give an incorrect integer.
> 
> If needed, one can add an explanation: "due to intermediate rounding";

Agree; I'll take it, with the "due to ..." too.

> or an example: ", e.g. on DBL_MAX".

I'll omit this.

Have a lovely day!
Alex

-- 
<https://www.alejandro-colomar.es/>
Looking for a remote C programming job at the moment.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] manual: logb(x) is floor(log2(fabs(x)))
  2024-03-05 10:02   ` Vincent Lefevre
  2024-03-05 11:10     ` Alejandro Colomar
@ 2024-03-05 13:16     ` Morten Welinder
  2024-03-05 15:01       ` Vincent Lefevre
  1 sibling, 1 reply; 7+ messages in thread
From: Morten Welinder @ 2024-03-05 13:16 UTC (permalink / raw)
  To: Vincent Lefevre, Alejandro Colomar, libc-alpha, Morten Welinder,
	Adhemerval Zanella Netto

> No, it isn't necessarily equal. The code floor (log2 (fabs ((x)))
> can give an incorrect result due to rounding if x is just before
> a power of 2, in particular if x is large.

Right you are.

However, the formula is meant as an explanation, not a C code
substitute, so I think a bit of rewording can fix it.  Something like

...works like "floor (log2 (fabs (x)))" if that formula is computed
without rounding of intermediate values.

Same story as fma really.

M.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] manual: logb(x) is floor(log2(fabs(x)))
  2024-03-05 13:16     ` Morten Welinder
@ 2024-03-05 15:01       ` Vincent Lefevre
  0 siblings, 0 replies; 7+ messages in thread
From: Vincent Lefevre @ 2024-03-05 15:01 UTC (permalink / raw)
  To: Morten Welinder; +Cc: Alejandro Colomar, libc-alpha, Adhemerval Zanella Netto

On 2024-03-05 08:16:09 -0500, Morten Welinder wrote:
> > No, it isn't necessarily equal. The code floor (log2 (fabs ((x)))
> > can give an incorrect result due to rounding if x is just before
> > a power of 2, in particular if x is large.
> 
> Right you are.
> 
> However, the formula is meant as an explanation, not a C code
> substitute, so I think a bit of rewording can fix it.  Something like
> 
> ...works like "floor (log2 (fabs (x)))" if that formula is computed
> without rounding of intermediate values.

I don't think that giving an explanation as code is a good idea.
Giving a math formula is OK, though. Also note that a math formula
could be given for any radix, not just 2: floor(log_b |x|). I think
that this is important since there are 3 conventions to define an
exponent. So this must be explicit in any radix.

BTW, "These functions extract the exponent from the internal
floating-point representation of x and return it as a floating-point
value." should not use the word "representation", because this has
nothing to do with the representation (think of numbers that are not
normalized). And "extract" is misleading too, because for numbers
that are not normalized, the exponent is not extracted.

Something like

  These functions return the exponent of the floating-point number x
  (in radix FLT_RADIX) as a floating-point value.

> Same story as fma really.

No, not really. For fma, this is a math formula followed by rounding.

-- 
Vincent Lefèvre <vincent@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-03-05 15:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <ZeZIVzJ_Wl42SnF2@debian>
2024-03-04 22:40 ` [PATCH] manual: logb(x) is floor(log2(fabs(x))) Alejandro Colomar
2024-03-05 10:02   ` Vincent Lefevre
2024-03-05 11:10     ` Alejandro Colomar
2024-03-05 11:37       ` Vincent Lefevre
2024-03-05 12:30         ` Alejandro Colomar
2024-03-05 13:16     ` Morten Welinder
2024-03-05 15:01       ` Vincent Lefevre

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).