amath
1.8.5
Simple command line calculator
|
Kernel reduction function. More...
#include "prim.h"
Go to the source code of this file.
Functions | |
int | __kernel_rem_pio2 (double *x, double *y, int e0, int nx, int prec, const int *ipio2) |
Kernel reduction function. More... | |
Variables | |
static const int | init_jk [] = {2,3,4,6} |
static const double | PIo2 [] |
static const double | zero = 0.0 |
static const double | one = 1.0 |
static const double | two24 = 1.67772160000000000000e+07 |
static const double | twon24 = 5.96046447753906250000e-08 |
Kernel reduction function.
Definition in file kremp2.c.
int __kernel_rem_pio2 | ( | double * | x, |
double * | y, | ||
int | e0, | ||
int | nx, | ||
int | prec, | ||
const int * | ipio2 | ||
) |
Kernel reduction function.
__kernel_rem_pio2(x,y,e0,nx,prec,ipio2) double x[],y[]; int e0,nx,prec; int ipio2[];
__kernel_rem_pio2 return the last three digits of N with y = x - N*pi/2 so that |y| < pi/2.
The method is to compute the integer (mod 8) and fraction parts of (2/pi)*x without doing the full multiplication. In general we skip the part of the product that are known to be a huge integer ( more accurately, = 0 mod 8 ). Thus the number of operations are independent of the exponent of the input.
(2/pi) is represented by an array of 24-bit integers in ipio2[].
Input parameters: x[] The input value (must be positive) is broken into nx pieces of 24-bit integers in double precision format. x[i] will be the i-th 24 bit of x. The scaled exponent of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 match x's up to 24 bits.
Example of breaking a double positive z into x[0]+x[1]+x[2]: e0 = ilogb(z)-23 z = scalbn(z,-e0) for i = 0,1,2 x[i] = floor(z) z = (z-x[i])*2**24
y[] ouput result in an array of double precision numbers. The dimension of y[] is: 24-bit precision 1 53-bit precision 2 64-bit precision 2 113-bit precision 3 The actual value is the sum of them. Thus for 113-bit precison, one may have to do something like:
long double t,w,r_head, r_tail; t = (long double)y[2] + (long double)y[1]; w = (long double)y[0]; r_head = t+w; r_tail = w - (r_head - t);
e0 The exponent of x[0]
nx dimension of x[]
prec an integer indicating the precision: 0 24 bits (single) 1 53 bits (double) 2 64 bits (extended) 3 113 bits (quad)
ipio2[] integer array, contains the (24*i)-th to (24*i+23)-th bit of 2/pi after binary point. The corresponding floating value isipio2[i] * 2^(-24(i+1)).
External function: double scalbn(), floor();
Here is the description of some local variables:jk jk+1 is the initial number of terms of ipio2[] needed in the computation. The recommended value is 2,3,4, 6 for single, double, extended,and quad. jz local integer variable indicating the number of terms of ipio2[] used.
jx nx - 1
jv index for pointing to the suitable ipio2[] for the computation. In general, we want ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 is an integer. Thus e0-3-24*jv >= 0 or (e0-3)/24 >= jv Hence jv = max(0,(e0-3)/24).
jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
q[] double array with integral value, representing the 24-bits chunk of the product of x and 2/pi.
q0 the corresponding exponent of q[0]. Note that the exponent for q[i] would be q0-24*i.
PIo2[] double precision array, obtained by cutting pi/2 into 24 bits chunks.
f[] ipio2[] in floating point
iq[] integer array by breaking up q[] in 24-bits chunk.
fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
ih integer. If >0 it indicates q[] is >= 0.5, hence it also indicates the sign of the result.
Definition at line 184 of file kremp2.c.
References floor(), init_jk, one, PIo2, scalbn(), two24, twon24, and zero.
Referenced by rempio2().
|
static |
Definition at line 56 of file kremp2.c.
Referenced by __kernel_rem_pio2().
|
static |
Definition at line 71 of file kremp2.c.
Referenced by __kernel_rem_pio2().
|
static |
Definition at line 58 of file kremp2.c.
Referenced by __kernel_rem_pio2().
|
static |
Definition at line 72 of file kremp2.c.
Referenced by __kernel_rem_pio2().
|
static |
Definition at line 73 of file kremp2.c.
Referenced by __kernel_rem_pio2().
|
static |
Definition at line 70 of file kremp2.c.
Referenced by __kernel_rem_pio2().