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