ReactOS 0.4.17-dev-1321-g5c122a9
__rem_pio2.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS CRT
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Implementation of __rem_pio2.
5 * COPYRIGHT: Imported from musl libc
6 * https://git.musl-libc.org/cgit/musl/tree/src/math/__rem_pio2.c
7 * blob: dcf672fbd70344d40b308cf0c0a11b862bea6dca
8 * See https://git.musl-libc.org/cgit/musl/tree/COPYRIGHT
9 */
10
11/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */
12/*
13 * ====================================================
14 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
15 *
16 * Developed at SunSoft, a Sun Microsystems, Inc. business.
17 * Permission to use, copy, modify, and distribute this
18 * software is freely granted, provided that this notice
19 * is preserved.
20 * ====================================================
21 *
22 * Optimized by Bruce D. Evans.
23 */
24/* __rem_pio2(x,y)
25 *
26 * return the remainder of x rem pi/2 in y[0]+y[1]
27 * use __rem_pio2_large() for large x
28 */
29
30#include "libm.h"
31
32#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
33#define EPS DBL_EPSILON
34#elif FLT_EVAL_METHOD==2
35#define EPS LDBL_EPSILON
36#endif
37
38/*
39 * invpio2: 53 bits of 2/pi
40 * pio2_1: first 33 bit of pi/2
41 * pio2_1t: pi/2 - pio2_1
42 * pio2_2: second 33 bit of pi/2
43 * pio2_2t: pi/2 - (pio2_1+pio2_2)
44 * pio2_3: third 33 bit of pi/2
45 * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
46 */
47static const double
48toint = 1.5/EPS,
49pio4 = 0x1.921fb54442d18p-1,
50invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
51pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
52pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
53pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
54pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
55pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
56pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
57
58/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
59int __rem_pio2(double x, double *y)
60{
61 union {double f; uint64_t i;} u = {x};
62 double_t z,w,t,r,fn;
63 double tx[3],ty[2];
64 uint32_t ix;
65 int sign, n, ex, ey, i;
66
67 sign = u.i>>63;
68 ix = u.i>>32 & 0x7fffffff;
69 if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */
70 if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */
71 goto medium; /* cancellation -- use medium case */
72 if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */
73 if (!sign) {
74 z = x - pio2_1; /* one round good to 85 bits */
75 y[0] = z - pio2_1t;
76 y[1] = (z-y[0]) - pio2_1t;
77 return 1;
78 } else {
79 z = x + pio2_1;
80 y[0] = z + pio2_1t;
81 y[1] = (z-y[0]) + pio2_1t;
82 return -1;
83 }
84 } else {
85 if (!sign) {
86 z = x - 2*pio2_1;
87 y[0] = z - 2*pio2_1t;
88 y[1] = (z-y[0]) - 2*pio2_1t;
89 return 2;
90 } else {
91 z = x + 2*pio2_1;
92 y[0] = z + 2*pio2_1t;
93 y[1] = (z-y[0]) + 2*pio2_1t;
94 return -2;
95 }
96 }
97 }
98 if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */
99 if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */
100 if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */
101 goto medium;
102 if (!sign) {
103 z = x - 3*pio2_1;
104 y[0] = z - 3*pio2_1t;
105 y[1] = (z-y[0]) - 3*pio2_1t;
106 return 3;
107 } else {
108 z = x + 3*pio2_1;
109 y[0] = z + 3*pio2_1t;
110 y[1] = (z-y[0]) + 3*pio2_1t;
111 return -3;
112 }
113 } else {
114 if (ix == 0x401921fb) /* |x| ~= 4pi/2 */
115 goto medium;
116 if (!sign) {
117 z = x - 4*pio2_1;
118 y[0] = z - 4*pio2_1t;
119 y[1] = (z-y[0]) - 4*pio2_1t;
120 return 4;
121 } else {
122 z = x + 4*pio2_1;
123 y[0] = z + 4*pio2_1t;
124 y[1] = (z-y[0]) + 4*pio2_1t;
125 return -4;
126 }
127 }
128 }
129 if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */
130medium:
131 /* rint(x/(pi/2)) */
133 n = (int32_t)fn;
134 r = x - fn*pio2_1;
135 w = fn*pio2_1t; /* 1st round, good to 85 bits */
136 /* Matters with directed rounding. */
137 if (predict_false(r - w < -pio4)) {
138 n--;
139 fn--;
140 r = x - fn*pio2_1;
141 w = fn*pio2_1t;
142 } else if (predict_false(r - w > pio4)) {
143 n++;
144 fn++;
145 r = x - fn*pio2_1;
146 w = fn*pio2_1t;
147 }
148 y[0] = r - w;
149 u.f = y[0];
150 ey = u.i>>52 & 0x7ff;
151 ex = ix>>20;
152 if (ex - ey > 16) { /* 2nd round, good to 118 bits */
153 t = r;
154 w = fn*pio2_2;
155 r = t - w;
156 w = fn*pio2_2t - ((t-r)-w);
157 y[0] = r - w;
158 u.f = y[0];
159 ey = u.i>>52 & 0x7ff;
160 if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */
161 t = r;
162 w = fn*pio2_3;
163 r = t - w;
164 w = fn*pio2_3t - ((t-r)-w);
165 y[0] = r - w;
166 }
167 }
168 y[1] = (r - y[0]) - w;
169 return n;
170 }
171 /*
172 * all other (large) arguments
173 */
174 if (ix >= 0x7ff00000) { /* x is inf or NaN */
175 y[0] = y[1] = x - x;
176 return 0;
177 }
178 /* set z = scalbn(|x|,-ilogb(x)+23) */
179 u.f = x;
180 u.i &= (uint64_t)-1>>12;
181 u.i |= (uint64_t)(0x3ff + 23)<<52;
182 z = u.f;
183 for (i=0; i < 2; i++) {
184 tx[i] = (double)(int32_t)z;
185 z = (z-tx[i])*0x1p24;
186 }
187 tx[i] = z;
188 /* skip zero terms, first term is non-zero */
189 while (tx[i] == 0.0)
190 i--;
191 n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);
192 if (sign) {
193 y[0] = -ty[0];
194 y[1] = -ty[1];
195 return -n;
196 }
197 y[0] = ty[0];
198 y[1] = ty[1];
199 return n;
200}
static const double invpio2
Definition: __rem_pio2.c:50
static const double pio2_1t
Definition: __rem_pio2.c:52
static const double pio2_2t
Definition: __rem_pio2.c:54
static const double pio4
Definition: __rem_pio2.c:49
#define EPS
Definition: __rem_pio2.c:33
static const double pio2_3t
Definition: __rem_pio2.c:56
int __rem_pio2(double x, double *y)
Definition: __rem_pio2.c:59
static const double toint
Definition: __rem_pio2.c:48
static const double pio2_1
Definition: __rem_pio2.c:51
static const double pio2_3
Definition: __rem_pio2.c:55
static const double pio2_2
Definition: __rem_pio2.c:53
int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec)
INT32 int32_t
Definition: types.h:71
UINT32 uint32_t
Definition: types.h:75
UINT64 uint64_t
Definition: types.h:77
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 t
Definition: gl.h:2047
GLdouble n
Definition: glext.h:7729
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLbyte ty
Definition: glext.h:8756
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
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 * u
Definition: glfuncs.h:240
#define f
Definition: ke_i.h:83
#define predict_false(x)
Definition: libm.h:93
#define sign(x)
Definition: mapdesc.cc:613
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:91
#define uint64_t
Definition: nsiface.idl:62
#define int32_t
Definition: nsiface.idl:56
Definition: comerr.c:44
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159