Accuracy of Math.Sin() and Math.Cos() in C#

前端 未结 6 1503
南旧
南旧 2020-12-16 04:58

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         


        
6条回答
  •  抹茶落季
    2020-12-16 05:06

    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.

提交回复
热议问题