I am terribly annoyed by the inaccuracy of the intrinsic trig functions in the CLR. It is well know that
Math.Sin(Math.PI)=0.0000000000000001224606353822377
I reject the idea the the errors are due to round-off. What can be done is define sin(x)
as follows, using a Taylor's expansion with 6 terms:
const double π=Math.PI;
const double π2=Math.PI/2;
const double π4=Math.PI/4;
public static double Sin(double x)
{
if (x==0) { return 0; }
if (x<0) { return -Sin(-x); }
if (x>π) { return -Sin(x-π); }
if (x>π4) { return Cos(π2-x); }
double x2=x*x;
return x*(x2/6*(x2/20*(x2/42*(x2/72*(x2/110*(x2/156-1)+1)-1)+1)-1)+1);
}
public static double Cos(double x)
{
if (x==0) { return 1; }
if (x<0) { return Cos(-x); }
if (x>π) { return -Cos(x-π); }
if (x>π4) { return Sin(π2-x); }
double x2=x*x;
return x2/2*(x2/12*(x2/30*(x2/56*(x2/90*(x2/132-1)+1)-1)+1)-1)+1;
}
Typical error is 1e-16
and worst case is 1e-11
. It is worse than the CLR, but it is controllable by adding more terms. The good news is that for the special cases in the OP and for Sin(45°)
the answer is exact.