/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
j = jv - jx;
m = jx + jk;
for (i = 0; i <= m; i++, j++)
f[i] = (j < 0) ? zero : (double)ipio2[j];
/* compute q[0],q[1],...q[jk] */
for (i = 0; i <= jk; i++)
{
for (j = 0, fw = 0.0; j <= jx; j++)
fw += x[j] * f[jx + i - j];
q[i] = fw;
}
jz = jk;
recompute: /* distill q[] into iq[] reversingly */
for (i = 0, j = jz, z = q[jz]; j > 0; i++, j--)
{
fw = (double)((int32_t)(twon24 * z));
iq[i] = (int)(z - two24 * fw);
z = q[j - 1] + fw;
}
/* compute n */
z = std::scalbn(z, q0); /* actual value of z */
z -= 8.0 * std::floor(z * 0.125); /* trim off integer >= 8 */
n = (int32_t)z;
z -= (double)n;
ih = 0;
if (q0 > 0)
{ /* need iq[jz-1] to determine n */
i = (iq[jz - 1] >> (24 - q0));
n += i;
iq[jz - 1] -= i << (24 - q0);
ih = iq[jz - 1] >> (23 - q0);
} else if (q0 == 0)
ih = iq[jz - 1] >> 23; else if (z >= 0.5)
ih = 2;
if (ih > 0)
{ /* q > 0.5 */
n += 1;
carry = 0;
for (i = 0; i < jz; i++)
{ /* compute 1-q */
j = iq[i];
if (carry == 0)
{
if (j != 0)
{
carry = 1;
iq[i] = 0x1000000 - j;
}
} else
iq[i] = 0xffffff - j;
}
if (q0 > 0)
{ /* rare case: chance is 1 in 12 */ switch (q0)
{ case1:
iq[jz - 1] &= 0x7fffff; break; case2:
iq[jz - 1] &= 0x3fffff; break;
}
}
if (ih == 2)
{
z = one - z;
if (carry != 0)
z -= std::scalbn(one, q0);
}
}
/* check if recomputation is needed */
if (z == zero)
{
j = 0;
for (i = jz - 1; i >= jk; i--)
j |= iq[i];
if (j == 0)
{ /* need recomputation */
for (k = 1; iq[jk - k] == 0; k++)
; /* k = no. of terms needed */
for (i = jz + 1; i <= jz + k; i++)
{ /* add q[jz+1] to q[jz+k] */
f[jx + i] = (double)ipio2[jv + i];
for (j = 0, fw = 0.0; j <= jx; j++)
fw += x[j] * f[jx + i - j];
q[i] = fw;
}
jz += k;
goto recompute;
}
}
/* chop off zero terms */
if (z == 0.0)
{
jz -= 1;
q0 -= 24; while (iq[jz] == 0)
{
jz--;
q0 -= 24;
}
} else
{ /* break z into 24-bit if necessary */
z = std::scalbn(z, -q0);
if (z >= two24)
{
fw = (double)((int32_t)(twon24 * z));
iq[jz] = (int32_t)(z - two24 * fw);
jz += 1;
q0 += 24;
iq[jz] = (int32_t)fw;
} else
iq[jz] = (int32_t)z;
}
/* convert integer "bit" chunk to floating-point value */
fw = scalbn(one, q0);
for (i = jz; i >= 0; i--)
{
q[i] = fw * (double)iq[i];
fw *= twon24;
}
/* compute PIo2[0,...,jp]*q[jz,...,0] */
for (i = jz; i >= 0; i--)
{
for (fw = 0.0, k = 0; k <= jp && k <= jz - i; k++)
fw += PIo2[k] * q[i + k];
fq[jz - i] = fw;
}
/* compress fq[] into y[] */ switch (prec)
{ case0:
fw = 0.0;
for (i = jz; i >= 0; i--)
fw += fq[i];
y[0] = (ih == 0) ? fw : -fw; break; case1: case2:
fw = 0.0;
for (i = jz; i >= 0; i--)
fw += fq[i];
y[0] = (ih == 0) ? fw : -fw;
fw = fq[0] - fw;
for (i = 1; i <= jz; i++)
fw += fq[i];
y[1] = (ih == 0) ? fw : -fw; break; case3: /* painful */
for (i = jz; i > 0; i--)
{
fw = fq[i - 1] + fq[i];
fq[i] += fq[i - 1] - fw;
fq[i - 1] = fw;
}
for (i = jz; i > 1; i--)
{
fw = fq[i - 1] + fq[i];
fq[i] += fq[i - 1] - fw;
fq[i - 1] = fw;
}
for (fw = 0.0, i = jz; i >= 2; i--)
fw += fq[i];
if (ih == 0)
{
y[0] = fq[0];
y[1] = fq[1];
y[2] = fw;
} else
{
y[0] = -fq[0];
y[1] = -fq[1];
y[2] = -fw;
}
} return n & 7;
}
double z = 0., w, t, r, fn; double tx[3];
std::int32_t e0, i, j, nx, n, ix, hx;
std::uint32_t low;
GET_HIGH_WORD(hx, x); /* high word of x */
ix = hx & 0x7fffffff;
if (ix <= 0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
{
y[0] = x;
y[1] = 0; return0;
}
if (ix < 0x4002d97c)
{ /* |x| < 3pi/4, special case with n=+-1 */
if (hx > 0)
{
z = x - pio2_1;
if (ix != 0x3ff921fb)
{ /* 33+53 bit pi is good enough */
y[0] = z - pio2_1t;
y[1] = (z - y[0]) - pio2_1t;
} else
{ /* near pi/2, use 33+33+53 bit pi */
z -= pio2_2;
y[0] = z - pio2_2t;
y[1] = (z - y[0]) - pio2_2t;
} return1;
} else
{ /* negative x */
z = x + pio2_1;
if (ix != 0x3ff921fb)
{ /* 33+53 bit pi is good enough */
y[0] = z + pio2_1t;
y[1] = (z - y[0]) + pio2_1t;
} else
{ /* near pi/2, use 33+33+53 bit pi */
z += pio2_2;
y[0] = z + pio2_2t;
y[1] = (z - y[0]) + pio2_2t;
}
return -1;
}
}
if (ix <= 0x413921fb)
{ /* |x| ~<= 2^19*(pi/2), medium_ size */
t = std::fabs(x);
n = (std::int32_t)(t * invpio2 + half);
fn = (double)n;
r = t - fn * pio2_1;
w = fn * pio2_1t; /* 1st round good to 85 bit */
if ((n < 32) && (n > 0) && (ix != npio2_hw[n - 1]))
{
y[0] = r - w; /* quick check no cancellation */
} else
{
std::uint32_t high;
j = ix >> 20;
y[0] = r - w;
GET_HIGH_WORD(high, y[0]);
i = j - static_cast<int32_t>((high >> 20) & 0x7ff);
if (i > 16)
{ /* 2nd iteration needed, good to 118 */
t = r;
w = fn * pio2_2;
r = t - w;
w = fn * pio2_2t - ((t - r) - w);
y[0] = r - w;
GET_HIGH_WORD(high, y[0]);
i = j - static_cast<int32_t>((high >> 20) & 0x7ff);
if (i > 49)
{ /* 3rd iteration need, 151 bits acc */
t = r; /* will cover all possible cases */
w = fn * pio2_3;
r = t - w;
w = fn * pio2_3t - ((t - r) - w);
y[0] = r - w;
}
}
}
y[1] = (r - y[0]) - w;
if (hx < 0)
{
y[0] = -y[0];
y[1] = -y[1]; return -n;
} else return n;
} /* *allother(large)arguments
*/
if (ix >= 0x7ff00000)
{ /* x is inf or NaN */
y[0] = y[1] = x - x; return0;
} /* set z = scalbn(|x|,ilogb(x)-23) */
GET_LOW_WORD(low, x);
SET_LOW_WORD(z, low);
e0 = (ix >> 20) - 1046; /* e0 = ilogb(z)-23; */
SET_HIGH_WORD(z, static_cast<uint32_t>(ix - (e0 << 20)));
for (i = 0; i < 2; i++)
{
tx[i] = (double)((std::int32_t)(z));
z = (z - tx[i]) * two24;
}
tx[2] = z;
nx = 3; while (tx[nx - 1] == zero)
nx--; /* skip zero term */
n = __kernel_rem_pio2(tx, y, e0, nx, 2, two_over_pi);
if (hx < 0)
{
y[0] = -y[0];
y[1] = -y[1]; return -n;
} return n;
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.