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类型进行计算。