bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

new modules 'log2', 'log2f', 'log2l'


From: Bruno Haible
Subject: new modules 'log2', 'log2f', 'log2l'
Date: Sun, 11 Mar 2012 23:39:31 +0100
User-agent: KMail/4.7.4 (Linux/3.1.0-1.2-desktop; KDE/4.7.4; x86_64; ; )

The functions log2(), log2f(), log2l() are easier to provide than the
previous ones.


Notable bugs:

OSF/1:
log2 (-0.0) = NaN (should be -Infinity)
log2f (-0.0f) = NaN (should be -Infinity)

Cygein 1.7.9:
log2 (2^29) = 29.0 + 3.55271e-15
log2 (2^13) != 13.0f

NetBSD 5.1, Solaris:
log2(), log2f() with negative arguments.


2012-03-11  Bruno Haible  <address@hidden>

        log2f-ieee: Work around test failure on NetBSD 5.1 and Solaris 10.
        * m4/log2f-ieee.m4: New file.
        * m4/log2f.m4 (gl_FUNC_LOG2F): If gl_FUNC_LOG2F_IEEE is present, test
        whether log2f works with a minus zero argument. Replace it if not.
        * modules/log2f-ieee (Files): Add m4/log2f-ieee.m4.
        (Depends-on): Add log2-ieee.
        (configure.ac): Invoke gl_FUNC_LOG2F_IEEE.
        * doc/posix-functions/log2f.texi: Mention the log2f-ieee module.

        log2-ieee: Work around test failure on NetBSD 5.1 and Solaris 10.
        * m4/log2-ieee.m4: New file.
        * m4/log2.m4 (gl_FUNC_LOG2): If gl_FUNC_LOG2_IEEE is present, test
        whether log2 works with a minus zero argument. Replace it if not.
        * modules/log2-ieee (Files): Add m4/log2-ieee.m4.
        (configure.ac): Invoke gl_FUNC_LOG2_IEEE.
        * doc/posix-functions/log2.texi: Mention the log2-ieee module.

        Tests for module 'log2l-ieee'.
        * modules/log2l-ieee-tests: New file.
        * tests/test-log2l-ieee.c: New file.

        New module 'log2l-ieee'.
        * modules/log2l-ieee: New file.

        Tests for module 'log2-ieee'.
        * modules/log2-ieee-tests: New file.
        * tests/test-log2-ieee.c: New file.

        New module 'log2-ieee'.
        * modules/log2-ieee: New file.

        Tests for module 'log2f-ieee'.
        * modules/log2f-ieee-tests: New file.
        * tests/test-log2f-ieee.c: New file.
        * tests/test-log2-ieee.h: New file.

        New module 'log2f-ieee'.
        * modules/log2f-ieee: New file.

2012-03-11  Bruno Haible  <address@hidden>

        Tests for module 'log2l'.
        * modules/log2l-tests: New file.
        * tests/test-log2l.c: New file.

        New module 'log2l'.
        * lib/math.in.h (log2l): New declaration.
        * lib/log2l.c: New file.
        * m4/log2l.m4: New file.
        * m4/math_h.m4 (gl_MATH_H): Test whether log2l is declared.
        (gl_MATH_H_DEFAULTS): Initialize GNULIB_LOG2L, HAVE_DECL_LOG2L,
        REPLACE_LOG2L.
        * modules/math (Makefile.am): Substitute GNULIB_LOG2L, HAVE_DECL_LOG2L,
        REPLACE_LOG2L.
        * modules/log2l: New file.
        * tests/test-math-c++.cc: Check the declaration of log2l.
        * doc/posix-functions/log2l.texi: Mention the new module and the IRIX
        and OSF/1 problems.

2012-03-11  Bruno Haible  <address@hidden>

        Tests for module 'log2f'.
        * modules/log2f-tests: New file.
        * tests/test-log2f.c: New file.

        New module 'log2f'.
        * lib/math.in.h (log2f): New declaration.
        * lib/log2f.c: New file.
        * m4/log2f.m4: New file.
        * m4/math_h.m4 (gl_MATH_H): Test whether log2f is declared.
        (gl_MATH_H_DEFAULTS): Initialize GNULIB_LOG2F, HAVE_DECL_LOG2F,
        REPLACE_LOG2F.
        * modules/math (Makefile.am): Substitute GNULIB_LOG2F, HAVE_DECL_LOG2F,
        REPLACE_LOG2F.
        * modules/log2f: New file.
        * tests/test-math-c++.cc: Check the declaration of log2f.
        * doc/posix-functions/log2f.texi: Mention the new module and the IRIX
        and OSF/1 and Cygwin problems.

2012-03-11  Bruno Haible  <address@hidden>

        Tests for module 'log2'.
        * modules/log2-tests: New file.
        * tests/test-log2.c: New file.
        * tests/test-log2.h: New file.

        New module 'log2'.
        * lib/math.in.h (log2): New declaration.
        * lib/log2.c: New file.
        * m4/log2.m4: New file.
        * m4/math_h.m4 (gl_MATH_H): Test whether log2 is declared.
        (gl_MATH_H_DEFAULTS): Initialize GNULIB_LOG2, HAVE_DECL_LOG2,
        REPLACE_LOG2.
        * modules/math (Makefile.am): Substitute GNULIB_LOG2, HAVE_DECL_LOG2,
        REPLACE_LOG2.
        * modules/log2: New file.
        * tests/test-math-c++.cc: Check the declaration of log2.
        * doc/posix-functions/log2.texi: Mention the new module and the IRIX
        and OSF/1 and Cygwin problems.

================================= lib/log2l.c =================================
/* Base 2 logarithm.
   Copyright (C) 2011-2012 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include <config.h>

/* Specification.  */
#include <math.h>

#if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE

long double
log2l (long double x)
{
  return log2 (x);
}

#else

/* Best possible approximation of log(2) as a 'long double'.  */
#define LOG2 0.693147180559945309417232121458176568075L

/* Best possible approximation of 1/log(2) as a 'long double'.  */
#define LOG2_INVERSE 1.44269504088896340735992468100189213743L

/* sqrt(0.5).  */
#define SQRT_HALF 0.707106781186547524400844362104849039284L

long double
log2l (long double x)
{
  if (isnanl (x))
    return x;

  if (x <= 0.0L)
    {
      if (x == 0.0L)
        /* Return -Infinity.  */
        return - HUGE_VALL;
      else
        {
          /* Return NaN.  */
#if defined _MSC_VER || (defined __sgi && !defined __GNUC__)
          static long double zero;
          return zero / zero;
#else
          return 0.0L / 0.0L;
#endif
        }
    }

  /* Decompose x into
       x = 2^e * y
     where
       e is an integer,
       1/2 < y < 2.
     Then log2(x) = e + log2(y) = e + log(y)/log(2).  */
  {
    int e;
    long double y;

    y = frexpl (x, &e);
    if (y < SQRT_HALF)
      {
        y = 2.0L * y;
        e = e - 1;
      }

    return (long double) e + logl (y) * LOG2_INVERSE;
  }
}

#endif




reply via email to

[Prev in Thread] Current Thread [Next in Thread]