mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-24 23:32:06 +00:00
85 lines
1.8 KiB
C
85 lines
1.8 KiB
C
|
|
||
|
/* @(#)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/range errors here. */
|
||
|
if (x == 0.0)
|
||
|
{
|
||
|
errno = ERANGE;
|
||
|
return (-z_infinity_f.f);
|
||
|
}
|
||
|
else if (x < 0.0)
|
||
|
{
|
||
|
errno = EDOM;
|
||
|
return (z_notanum_f.f);
|
||
|
}
|
||
|
else if (!isfinite(x))
|
||
|
{
|
||
|
if (isnanf(x))
|
||
|
return (z_notanum_f.f);
|
||
|
else
|
||
|
return (z_infinity_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);
|
||
|
}
|