Skip to content

Instantly share code, notes, and snippets.

@relrod
Created November 25, 2014 04:52
Show Gist options
  • Save relrod/1e0c4acb236b78a2e723 to your computer and use it in GitHub Desktop.
Save relrod/1e0c4acb236b78a2e723 to your computer and use it in GitHub Desktop.
What could /possibly/ go wrong?
double
SECTION
__sin (double x)
{
double xx, res, t, cor, y, s, c, sn, ssn, cs, ccs, xn, a, da, db, eps, xn1,
xn2;
mynumber u, v;
int4 k, m, n;
double retval = 0;
SET_RESTORE_ROUND_53BIT (FE_TONEAREST);
u.x = x;
m = u.i[HIGH_HALF];
k = 0x7fffffff & m; /* no sign */
if (k < 0x3e500000) /* if x->0 =>sin(x)=x */
retval = x;
/*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
else if (k < 0x3fd00000)
{
xx = x * x;
/* Taylor series. */
t = POLYNOMIAL (xx) * (xx * x);
res = x + t;
cor = (x - res) + t;
retval = (res == res + 1.07 * cor) ? res : slow (x);
} /* else if (k < 0x3fd00000) */
/*---------------------------- 0.25<|x|< 0.855469---------------------- */
else if (k < 0x3feb6000)
{
u.x = (m > 0) ? big + x : big - x;
y = (m > 0) ? x - (u.x - big) : x + (u.x - big);
xx = y * y;
s = y + y * xx * (sn3 + xx * sn5);
c = xx * (cs2 + xx * (cs4 + xx * cs6));
SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs);
if (m <= 0)
{
sn = -sn;
ssn = -ssn;
}
cor = (ssn + s * ccs - sn * c) + cs * s;
res = sn + cor;
cor = (sn - res) + cor;
retval = (res == res + 1.096 * cor) ? res : slow1 (x);
} /* else if (k < 0x3feb6000) */
/*----------------------- 0.855469 <|x|<2.426265 ----------------------*/
else if (k < 0x400368fd)
{
y = (m > 0) ? hp0 - x : hp0 + x;
if (y >= 0)
{
u.x = big + y;
y = (y - (u.x - big)) + hp1;
}
else
{
u.x = big - y;
y = (-hp1) - (y + (u.x - big));
}
res = do_cos (u, y, &cor);
retval = (res == res + 1.020 * cor) ? ((m > 0) ? res : -res) : slow2 (x);
} /* else if (k < 0x400368fd) */
/*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
else if (k < 0x419921FB)
{
t = (x * hpinv + toint);
xn = t - toint;
v.x = t;
y = (x - xn * mp1) - xn * mp2;
n = v.i[LOW_HALF] & 3;
da = xn * mp3;
a = y - da;
da = (y - a) - da;
eps = ABS (x) * 1.2e-30;
switch (n)
{ /* quarter of unit circle */
case 0:
case 2:
xx = a * a;
if (n)
{
a = -a;
da = -da;
}
if (xx < 0.01588)
{
/* Taylor series. */
res = TAYLOR_SIN (xx, a, da, cor);
cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps;
retval = (res == res + cor) ? res : sloww (a, da, x);
}
else
{
if (a > 0)
m = 1;
else
{
m = 0;
a = -a;
da = -da;
}
u.x = big + a;
y = a - (u.x - big);
res = do_sin (u, y, da, &cor);
cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
retval = ((res == res + cor) ? ((m) ? res : -res)
: sloww1 (a, da, x, m));
}
break;
case 1:
case 3:
if (a < 0)
{
a = -a;
da = -da;
}
u.x = big + a;
y = a - (u.x - big) + da;
res = do_cos (u, y, &cor);
cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
retval = ((res == res + cor) ? ((n & 2) ? -res : res)
: sloww2 (a, da, x, n));
break;
}
} /* else if (k < 0x419921FB ) */
/*---------------------105414350 <|x|< 281474976710656 --------------------*/
else if (k < 0x42F00000)
{
t = (x * hpinv + toint);
xn = t - toint;
v.x = t;
xn1 = (xn + 8.0e22) - 8.0e22;
xn2 = xn - xn1;
y = ((((x - xn1 * mp1) - xn1 * mp2) - xn2 * mp1) - xn2 * mp2);
n = v.i[LOW_HALF] & 3;
da = xn1 * pp3;
t = y - da;
da = (y - t) - da;
da = (da - xn2 * pp3) - xn * pp4;
a = t + da;
da = (t - a) + da;
eps = 1.0e-24;
switch (n)
{
case 0:
case 2:
xx = a * a;
if (n)
{
a = -a;
da = -da;
}
if (xx < 0.01588)
{
/* Taylor series. */
res = TAYLOR_SIN (xx, a, da, cor);
cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps;
retval = (res == res + cor) ? res : bsloww (a, da, x, n);
}
else
{
double t;
if (a > 0)
{
m = 1;
t = a;
db = da;
}
else
{
m = 0;
t = -a;
db = -da;
}
u.x = big + t;
y = t - (u.x - big);
res = do_sin (u, y, db, &cor);
cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
retval = ((res == res + cor) ? ((m) ? res : -res)
: bsloww1 (a, da, x, n));
}
break;
case 1:
case 3:
if (a < 0)
{
a = -a;
da = -da;
}
u.x = big + a;
y = a - (u.x - big) + da;
res = do_cos (u, y, &cor);
cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
retval = ((res == res + cor) ? ((n & 2) ? -res : res)
: bsloww2 (a, da, x, n));
break;
}
} /* else if (k < 0x42F00000 ) */
/* -----------------281474976710656 <|x| <2^1024----------------------------*/
else if (k < 0x7ff00000)
retval = reduce_and_compute (x, 0);
/*--------------------- |x| > 2^1024 ----------------------------------*/
else
{
if (k == 0x7ff00000 && u.i[LOW_HALF] == 0)
__set_errno (EDOM);
retval = x / x;
}
return retval;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment