ReactOS 0.4.17-dev-1321-g5c122a9
__rem_pio2_large.c File Reference
#include "libm.h"
Include dependency graph for __rem_pio2_large.c:

Go to the source code of this file.

Functions

int __rem_pio2_large (double *x, double *y, int e0, int nx, int prec)
 

Variables

static const int init_jk [] = {3,4,4,6}
 
static const int32_t ipio2 []
 
static const double PIo2 []
 

Function Documentation

◆ __rem_pio2_large()

int __rem_pio2_large ( double *  x,
double *  y,
int  e0,
int  nx,
int  prec 
)

Definition at line 283 of file __rem_pio2_large.c.

284{
285 int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
286 double z,fw,f[20],fq[20],q[20];
287
288 /* initialize jk*/
289 jk = init_jk[prec];
290 jp = jk;
291
292 /* determine jx,jv,q0, note that 3>q0 */
293 jx = nx-1;
294 jv = (e0-3)/24; if(jv<0) jv=0;
295 q0 = e0-24*(jv+1);
296
297 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
298 j = jv-jx; m = jx+jk;
299 for (i=0; i<=m; i++,j++)
300 f[i] = j<0 ? 0.0 : (double)ipio2[j];
301
302 /* compute q[0],q[1],...q[jk] */
303 for (i=0; i<=jk; i++) {
304 for (j=0,fw=0.0; j<=jx; j++)
305 fw += x[j]*f[jx+i-j];
306 q[i] = fw;
307 }
308
309 jz = jk;
310recompute:
311 /* distill q[] into iq[] reversingly */
312 for (i=0,j=jz,z=q[jz]; j>0; i++,j--) {
313 fw = (double)(int32_t)(0x1p-24*z);
314 iq[i] = (int32_t)(z - 0x1p24*fw);
315 z = q[j-1]+fw;
316 }
317
318 /* compute n */
319 z = scalbn(z,q0); /* actual value of z */
320 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
321 n = (int32_t)z;
322 z -= (double)n;
323 ih = 0;
324 if (q0 > 0) { /* need iq[jz-1] to determine n */
325 i = iq[jz-1]>>(24-q0); n += i;
326 iq[jz-1] -= i<<(24-q0);
327 ih = iq[jz-1]>>(23-q0);
328 }
329 else if (q0 == 0) ih = iq[jz-1]>>23;
330 else if (z >= 0.5) ih = 2;
331
332 if (ih > 0) { /* q > 0.5 */
333 n += 1; carry = 0;
334 for (i=0; i<jz; i++) { /* compute 1-q */
335 j = iq[i];
336 if (carry == 0) {
337 if (j != 0) {
338 carry = 1;
339 iq[i] = 0x1000000 - j;
340 }
341 } else
342 iq[i] = 0xffffff - j;
343 }
344 if (q0 > 0) { /* rare case: chance is 1 in 12 */
345 switch(q0) {
346 case 1:
347 iq[jz-1] &= 0x7fffff; break;
348 case 2:
349 iq[jz-1] &= 0x3fffff; break;
350 }
351 }
352 if (ih == 2) {
353 z = 1.0 - z;
354 if (carry != 0)
355 z -= scalbn(1.0,q0);
356 }
357 }
358
359 /* check if recomputation is needed */
360 if (z == 0.0) {
361 j = 0;
362 for (i=jz-1; i>=jk; i--) j |= iq[i];
363 if (j == 0) { /* need recomputation */
364 for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
365
366 for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
367 f[jx+i] = (double)ipio2[jv+i];
368 for (j=0,fw=0.0; j<=jx; j++)
369 fw += x[j]*f[jx+i-j];
370 q[i] = fw;
371 }
372 jz += k;
373 goto recompute;
374 }
375 }
376
377 /* chop off zero terms */
378 if (z == 0.0) {
379 jz -= 1;
380 q0 -= 24;
381 while (iq[jz] == 0) {
382 jz--;
383 q0 -= 24;
384 }
385 } else { /* break z into 24-bit if necessary */
386 z = scalbn(z,-q0);
387 if (z >= 0x1p24) {
388 fw = (double)(int32_t)(0x1p-24*z);
389 iq[jz] = (int32_t)(z - 0x1p24*fw);
390 jz += 1;
391 q0 += 24;
392 iq[jz] = (int32_t)fw;
393 } else
394 iq[jz] = (int32_t)z;
395 }
396
397 /* convert integer "bit" chunk to floating-point value */
398 fw = scalbn(1.0,q0);
399 for (i=jz; i>=0; i--) {
400 q[i] = fw*(double)iq[i];
401 fw *= 0x1p-24;
402 }
403
404 /* compute PIo2[0,...,jp]*q[jz,...,0] */
405 for(i=jz; i>=0; i--) {
406 for (fw=0.0,k=0; k<=jp && k<=jz-i; k++)
407 fw += PIo2[k]*q[i+k];
408 fq[jz-i] = fw;
409 }
410
411 /* compress fq[] into y[] */
412 switch(prec) {
413 case 0:
414 fw = 0.0;
415 for (i=jz; i>=0; i--)
416 fw += fq[i];
417 y[0] = ih==0 ? fw : -fw;
418 break;
419 case 1:
420 case 2:
421 fw = 0.0;
422 for (i=jz; i>=0; i--)
423 fw += fq[i];
424 // TODO: drop excess precision here once double_t is used
425 fw = (double)fw;
426 y[0] = ih==0 ? fw : -fw;
427 fw = fq[0]-fw;
428 for (i=1; i<=jz; i++)
429 fw += fq[i];
430 y[1] = ih==0 ? fw : -fw;
431 break;
432 case 3: /* painful */
433 for (i=jz; i>0; i--) {
434 fw = fq[i-1]+fq[i];
435 fq[i] += fq[i-1]-fw;
436 fq[i-1] = fw;
437 }
438 for (i=jz; i>1; i--) {
439 fw = fq[i-1]+fq[i];
440 fq[i] += fq[i-1]-fw;
441 fq[i-1] = fw;
442 }
443 for (fw=0.0,i=jz; i>=2; i--)
444 fw += fq[i];
445 if (ih==0) {
446 y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
447 } else {
448 y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
449 }
450 }
451 return n&7;
452}
static const int32_t ipio2[]
static const double PIo2[]
static const int init_jk[]
INT32 int32_t
Definition: types.h:71
_ACRTIMP double __cdecl scalbn(double, int)
Definition: scalbn.c:14
_ACRTIMP double __cdecl floor(double)
Definition: floor.c:18
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 GLdouble q
Definition: gl.h:2063
GLdouble n
Definition: glext.h:7729
GLfloat f
Definition: glext.h:7540
GLfloat GLfloat GLfloat GLfloat nx
Definition: glext.h:8898
GLdouble GLdouble z
Definition: glext.h:5874
const GLfloat * m
Definition: glext.h:10848
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 const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:91
#define int32_t
Definition: nsiface.idl:56

Referenced by __rem_pio2().

Variable Documentation

◆ init_jk

const int init_jk[] = {3,4,4,6}
static

Definition at line 137 of file __rem_pio2_large.c.

Referenced by __rem_pio2_large().

◆ ipio2

const int32_t ipio2[]
static

Definition at line 151 of file __rem_pio2_large.c.

Referenced by __rem_pio2_large().

◆ PIo2

const double PIo2[]
static
Initial value:
= {
1.57079625129699707031e+00,
7.54978941586159635335e-08,
5.39030252995776476554e-15,
3.28200341580791294123e-22,
1.27065575308067607349e-29,
1.22933308981111328932e-36,
2.73370053816464559624e-44,
2.16741683877804819444e-51,
}

Definition at line 272 of file __rem_pio2_large.c.

Referenced by __rem_pio2_large().