Welcome to mirror list, hosted at ThFree Co, Russian Federation.

sf_logarithm.c « mathfp « libm « newlib - cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 224482f133d3f4cc1383a2f7fce4351fa10f47f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

/* @(#)z_logarithmf.c 1.0 98/08/13 */
/******************************************************************
 * The following routines are coded directly from the algorithms
 * and coefficients given in "Software Manual for the Elementary
 * Functions" by William J. Cody, Jr. and William Waite, Prentice
 * Hall, 1980.
 ******************************************************************/
/******************************************************************
 * Logarithm
 *
 * Input:
 *   x - floating point value
 *   ten - indicates base ten numbers
 *
 * Output:
 *   logarithm of x
 *
 * Description:
 *   This routine calculates logarithms.
 *
 *****************************************************************/

#include "fdlibm.h"
#include "zmath.h"

static const float a[] = { -0.5527074855 };
static const float b[] = { -0.6632718214e+1 };
static const float C1 = 0.693145752;
static const float C2 = 1.428606820e-06;
static const float C3 = 0.4342944819;

float
_DEFUN (logarithmf, (float, int),
        float x _AND
        int ten)
{
  int N;
  float f, w, z;

  /* Check for domain error here. */
  if (x <= 0.0)
    {
      errno = ERANGE;
      return (z_notanum_f.f);
    }

  /* Get the exponent and mantissa where x = f * 2^N. */
  f = frexpf (x, &N);

  z = f - 0.5;

  if (f > __SQRT_HALF)
    z = (z - 0.5) / (f * 0.5 + 0.5);
  else
    {
      N--;
      z /= (z * 0.5 + 0.5);
    }
  w = z * z;

  /* Use Newton's method with 4 terms. */
  z += z * w * (a[0]) / ((w + 1.0) * w + b[0]);

  if (N != 0)
    z = (N * C2 + z) + N * C1;

  if (ten)
    z *= C3;

  return (z);
}