ReactOS 0.4.17-dev-1321-g5c122a9
log.c File Reference
#include <math.h>
#include <stdint.h>
#include "libm.h"
#include "log_data.h"
Include dependency graph for log.c:

Go to the source code of this file.

Macros

#define T   __log_data.tab
 
#define T2   __log_data.tab2
 
#define B   __log_data.poly1
 
#define A   __log_data.poly
 
#define Ln2hi   __log_data.ln2hi
 
#define Ln2lo   __log_data.ln2lo
 
#define N   (1 << LOG_TABLE_BITS)
 
#define OFF   0x3fe6000000000000
 
#define LO   asuint64(1.0 - 0x1p-4)
 
#define HI   asuint64(1.0 + 0x1.09p-4)
 

Functions

static uint32_t top16 (double x)
 
double log (double x)
 

Macro Definition Documentation

◆ A

#define A   __log_data.poly

Definition at line 30 of file log.c.

◆ B

#define B   __log_data.poly1

Definition at line 29 of file log.c.

◆ HI

#define HI   asuint64(1.0 + 0x1.09p-4)

◆ Ln2hi

#define Ln2hi   __log_data.ln2hi

Definition at line 31 of file log.c.

◆ Ln2lo

#define Ln2lo   __log_data.ln2lo

Definition at line 32 of file log.c.

◆ LO

#define LO   asuint64(1.0 - 0x1p-4)

◆ N

#define N   (1 << LOG_TABLE_BITS)

Definition at line 33 of file log.c.

◆ OFF

#define OFF   0x3fe6000000000000

Definition at line 34 of file log.c.

◆ T

Definition at line 27 of file log.c.

◆ T2

Definition at line 28 of file log.c.

Function Documentation

◆ log()

double log ( double  x)

Definition at line 42 of file log.c.

43{
44 double_t w, z, r, r2, r3, y, invc, logc, kd, hi, lo;
45 uint64_t ix, iz, tmp;
47 int k, i;
48
49 ix = asuint64(x);
50 top = top16(x);
51#define LO asuint64(1.0 - 0x1p-4)
52#define HI asuint64(1.0 + 0x1.09p-4)
53 if (predict_false(ix - LO < HI - LO)) {
54 /* Handle close to 1.0 inputs separately. */
55 /* Fix sign of zero with downward rounding when x==1. */
56 if (WANT_ROUNDING && predict_false(ix == asuint64(1.0)))
57 return 0;
58 r = x - 1.0;
59 r2 = r * r;
60 r3 = r * r2;
61 y = r3 *
62 (B[1] + r * B[2] + r2 * B[3] +
63 r3 * (B[4] + r * B[5] + r2 * B[6] +
64 r3 * (B[7] + r * B[8] + r2 * B[9] + r3 * B[10])));
65 /* Worst-case error is around 0.507 ULP. */
66 w = r * 0x1p27;
67 double_t rhi = r + w - w;
68 double_t rlo = r - rhi;
69 w = rhi * rhi * B[0]; /* B[0] == -0.5. */
70 hi = r + w;
71 lo = r - hi + w;
72 lo += B[0] * rlo * (rhi + r);
73 y += lo;
74 y += hi;
75 return eval_as_double(y);
76 }
77 if (predict_false(top - 0x0010 >= 0x7ff0 - 0x0010)) {
78 /* x < 0x1p-1022 or inf or nan. */
79 if (ix * 2 == 0)
80 return __math_divzero(1);
81 if (ix == asuint64(INFINITY)) /* log(inf) == inf. */
82 return x;
83 if ((top & 0x8000) || (top & 0x7ff0) == 0x7ff0)
84 return __math_invalid(x);
85 /* x is subnormal, normalize it. */
86 ix = asuint64(x * 0x1p52);
87 ix -= 52ULL << 52;
88 }
89
90 /* x = 2^k z; where z is in range [OFF,2*OFF) and exact.
91 The range is split into N subintervals.
92 The ith subinterval contains z and c is near its center. */
93 tmp = ix - OFF;
94 i = (tmp >> (52 - LOG_TABLE_BITS)) % N;
95 k = (int64_t)tmp >> 52; /* arithmetic shift */
96 iz = ix - (tmp & 0xfffULL << 52);
97 invc = T[i].invc;
98 logc = T[i].logc;
99 z = asdouble(iz);
100
101 /* log(x) = log1p(z/c-1) + log(c) + k*Ln2. */
102 /* r ~= z/c - 1, |r| < 1/(2*N). */
103#if __FP_FAST_FMA
104 /* rounding error: 0x1p-55/N. */
105 r = __builtin_fma(z, invc, -1.0);
106#else
107 /* rounding error: 0x1p-55/N + 0x1p-66. */
108 r = (z - T2[i].chi - T2[i].clo) * invc;
109#endif
110 kd = (double_t)k;
111
112 /* hi + lo = r + log(c) + k*Ln2. */
113 w = kd * Ln2hi + logc;
114 hi = w + r;
115 lo = w - hi + r + kd * Ln2lo;
116
117 /* log(x) = lo + (log1p(r) - r) + hi. */
118 r2 = r * r; /* rounding error: 0x1p-54/N^2. */
119 /* Worst case error if |y| > 0x1p-5:
120 0.5 + 4.13/N + abs-poly-error*2^57 ULP (+ 0.002 ULP without fma)
121 Worst case error if |y| > 0x1p-4:
122 0.5 + 2.06/N + abs-poly-error*2^56 ULP (+ 0.001 ULP without fma). */
123 y = lo + r2 * A[0] +
124 r * r2 * (A[1] + r * A[2] + r2 * (A[3] + r * A[4])) + hi;
125 return eval_as_double(y);
126}
double __math_divzero(uint32_t sign)
double __math_invalid(double x)
Definition: ehthrow.cxx:93
Definition: ehthrow.cxx:54
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
#define INFINITY
Definition: math.h:272
static const uint32_t k[]
Definition: sha256.c:24
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLdouble GLdouble z
Definition: glext.h:5874
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static double asdouble(uint64_t i)
Definition: libm.h:142
static uint64_t asuint64(double f)
Definition: libm.h:135
static double eval_as_double(double x)
Definition: libm.h:102
#define predict_false(x)
Definition: libm.h:93
#define WANT_ROUNDING
Definition: libm.h:76
#define LOG_TABLE_BITS
Definition: log_data.h:20
static DNS_RECORDW r3
Definition: record.c:39
static DNS_RECORDW r2
Definition: record.c:38
#define int64_t
Definition: nsiface.idl:57
#define N
Definition: log.c:33
#define T
Definition: log.c:27
#define T2
Definition: log.c:28
#define OFF
Definition: log.c:34
#define HI
#define Ln2hi
Definition: log.c:31
#define Ln2lo
Definition: log.c:32
static uint32_t top16(double x)
Definition: log.c:37
#define LO

◆ top16()

static uint32_t top16 ( double  x)
inlinestatic

Definition at line 37 of file log.c.

38{
39 return asuint64(x) >> 48;
40}

Referenced by log().