C#中提高三角函数计算精度

版本:VS2008  C# 

作者:xmwang

方法一:三角函数分解计算提升精度

C#中Math.Sin进行三角函数计算,输入参数必须为double型,double型的有效位数相对decimal的28位要小很多,笔者认为可以将decimal类型分解为多个double类型进行三角函数计算,比如:Sin(decimalData)=Sin(doubleData1 + doubleData2)= Sin(doubleData1)Cos(doubleData2)+Cos(doubleData1)Sin(doubleData2),0.0000025423423432541231579844M分解为0.00000254234234和0.0000000000000032541231579844M这个两个数的有效位都没超过double的有效位表示范围,得到的结果就相对精确。代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            decimal x = 0.0000000025423423431231579844M;
            Console.WriteLine(x.ToString());
            Console.WriteLine(Math.Sin((double)x).ToString());
            Console.WriteLine(DecimalSin(x).ToString());
            Console.ReadLine();
        }
        static decimal DecimalSin(decimal x)
        {
            decimal x_long = x * 1000000000000;
            long x_part1 = (long)x_long;
            if (x_long - x_part1 < 0)
                x_part1--;
            double a = (double)(((decimal)x_part1) / 1000000000000);
            double b = (double)(x - (decimal)a);
            decimal result = ((decimal)Math.Sin(a)) * ((decimal)Math.Cos(b)) + ((decimal)Math.Cos(a)) * ((decimal)Math.Sin(b));
            return result;
        }
        static decimal DecimalCos(decimal x)
        {
            decimal x_long = x * 1000000000000;
            long x_part1 = (long)x_long;
            if (x_long - x_part1 < 0)
                x_part1--;
            double a = (double)(((decimal)x_part1) / 1000000000000);
            double b = (double)(x - (decimal)a);
            decimal result = ((decimal)Math.Cos(a)) * ((decimal)Math.Cos(b)) - ((decimal)Math.Sin(a)) * ((decimal)Math.Sin(b));
            return result;
        }
    }
}

直接用Math.Sin函数:2.54234234312316E-06
用三角函数分解后的方法:0.00000000254234234325138315798
微软自带科学计算器计算结果:2.5423423431231579816612597661325e-9
很明显三角函数分解后的方法精度要高很多,根据需要可以进行多次分解,或分解成多段double类型数值
进行计算,把握的原则是分解后确保数值不超过double计算的有效位数

 

方法二:

进行泰勒级分解,自己根据精度需求确定分解的级数。泰勒分解中的运算都是普通计算,可以直接用decimal类型进行计算。

posted @ 2011-09-20 13:44  xmwang  阅读(2894)  评论(0编辑  收藏  举报