数学函数编译器,源代码免费提供!!!超快!
最近我在完成大四毕业论文时,作了一个可以在程序中动态编译数学函数的编译器类(Delphi版,支持大多数基本数学函数,并支持多重定积分),我用它编写了一个“多元非线性回归分析”。
“编译类”动态编译的函数执行速度与Delphi6静态编译的函数执行速度相当,在一些时候(在具体的应用中这种情形很多)甚至比Delphi6编译的平均快出35%。
需要源代码的请在本贴子之后跟贴,贴中告知邮箱地址或给我发一封邮件HouSisong@263.net,发现任何错误请转告我,不慎感激!
部分源代码: //////////////////////////////////////////////////////////////////////////
// //
// 编译单元(包括实数函数和积分函数)TCompile //
// 作者:侯思松 2002.4 ,HouSisong@263.net //
// (转载时请保留本说明) //
// //
//////////////////////////////////////////////////////////////////////////
{
1.支持带参数编译,参数默认值为0;运行前请赋值;
2.常数可以用科学计数法表示,如: -1.4E-4=-0.00014;
系统定义的常数: 圆周率 PI=3.1415926535897932384626433832795
自然数 e=2.7182818284590452353602874713527
(允许重新赋值)
3.使用多重括号并不会降低速度,特别是在不容易分清楚计算优先级的时候,请多使用括号;
4.表达式中函数名和参数名等不区分大小写;
5.系统使用的标识符除去下面列出的函数名(包括别名)外还有 :
'Const_SYS_N' 、'Const_ff_SYS_x_N'和 'ff_SYS_N' ,自定义的参数名称请不要再次使用它们;
如果参数名称为 'PI' 和 'e' ,那默认值见上面,但这只是它的默认值,程序中可以重新赋值;
6.支持的函数:
算符(函数)名称 书写格式 例子
+ 加法 x+y 或者: Add(x,y) 3.5+5=8.5
- 减法 x-y 或者: Sub(x,y) 8-3=5
* 乘法 x*y 或者: Mul(x,y) 2*3=6
/ 除法 x/y 或者: Div(x,y) 3/2=1.5
\ 整除 x\y 或者: DivE(x,y) 25\10=2
Mod 求余 x mod y 或者: Mod(x,y) 14 mod 5=4
^ 指数 x^y 或者: power(x,y) 2^3=8
Max 最大值 Max(x,y) Max(3,4)=4
Min 最小值 Min(x,y) Min(3,4)=3
Sqr 平方 Sqr(x) Sqr(3)=9 //注意平方和开方的函数名称
Sqrt 开方 Sqrt(x) Sqrt(3)=1.73205080756888
Sin 正弦 Sin(x) Sin(pi/6)=0.5
Cos 余弦 Cos(x) Cos(0)=1
Tan 正切 Tan(x) 或者: tg(x) Tan(pi/4)=1
ArcSin 反正弦 ArcSin(x) 或者: ASin(x) ArcSin(1)=1.5707963267949=pi/2
ArcCos 反余弦 ArcCos(x) 或者: ACos(x) ArcCos(0)=1
ArcTan 反正切 Arctan(x) 或者: ATan(x)、Atn(x)、Arctg(x) Arctan(1)=0.785398163397448=pi/4
ArcTan2 反正切2 Arctan2(y,x) Arctan2(2,1)=1.10714871779409
Exp 自然指数 Exp(x) Exp(2)=e*e=e^2
Ln 自然对数 Ln(x) Ln(e)=1
Log 10的对数 Log(x) 或者: Log10(x) Log(100)=2
Log2 2的对数 Log2(x) Log2(8)=3
Abs 绝对值 Abs(x) Abs(-2)=2 ; Abs(2)=2
Int 取整 Int(x) 或者: Floor(x) Int(2.3)=2 ; Int(-2.3)=-3
Sgn 符号函数 Sgn(x) Sgn(-2)=-1 ; Sgn(0)=0 ; Sgn(2)=1
Sinh 双曲正弦 Sinh(x) Sinh(2)=3.62686040784702=(e^2-e^(-2))/2
Cosh 双曲余弦 Cosh(x) Cosh(2)=3.76219569108363=(e^2+e^(-2))/2
Tanh 双曲正切 Tanh(x) 或者: tgh(x) Tanh(2)=0.964027580075817=Sinh(2)/Cosh(2)
ArcSinh 反双曲正弦 ArcSinh(x) 或者: ASinh(x) ArcSinh(3.62686040784702)=2
ArcCosh 反双曲余弦 ArcCosh(x) 或者: ACosh(x) ArcCosh(3.76219569108363)=2
ArcTanh 反双曲正切 Arctanh(x) 或者: ATanh(x)、Arctgh(x) Arctanh(0.761594155955765)=1
ff 定积分函数 ff(a,b,x,g(x)) 或者: ff(a,b,x,N,g(x)) ff(-1,1,y,sqrt(1-y*y))=pi/2
(ff函数特别说明:
函数g(x)是关于'x'的函数,这里的自变量x与本函数ff以外的x没有关系;
ff函数表示 对函数 g(x) 从 a 积到 b 积分,
x表示g(x)是关于x的函数, N 表示 把积分区间分成 N 份来积 ,省略 N 时默认为 1000 ;
积分函数支持多重积分
(注意: 多重积分和积分套嵌不是一个意思)
比如求单位球体的体积(R=1)
二重积分表达式为:
ff(-1,1,x,
ff(-sqrt(1-x*x),sqrt(1-x*x),y,2*sqrt(1-x*x-y*y))
)
=4.18883330446894
=4*Pi/3
=ff(-1,1,x,PI*(1-x*x)); // (求单位球体体积的一重积分表达式)
}
interface
uses SysUtils, Classes, Math;
type TFunctionList =record
FName :string; //函数名称
FAddress :Pointer; //函数地址入口
FCCount :0..2; //函数所需参数个数
end;
type TParameterList =record
CName :String; //参数名称
CAddress :PExtended; //参数地址
IfConst :boolean; //是否为常数 false:常数 true:变量
end;
type TT_PTrue=record
ifConst :boolean; //编译优化常数时 参数性质 是否为常数
dValue :Extended; //编译优化常数时 参数性质 值
end;
Const SmallLimit: Extended = 1E-300; {无穷小}
Const LargeLimit: Extended = 1E+300; {无穷大}
const iBufC=256*1024; // 编译空间大小
type
TCompile=class // '编译' 类
{对外可见函数}
//Enabled :boolean; // 是否有效
function SetText(const str:string):boolean; //设置需要编译的字符串
Procedure GetValue(var x:Extended); //返回表达式的值 ,通过 x 返回。
function SetParameter(const PName:string;const dValue:Extended):boolean;overload; //按参数名称设置参数值
function GetParameterAddress(const PName:string):PExtended; //得到参数地址
procedure SetParameter(const PAddress:PExtended;const dValue:Extended);overload; //按参数地址设置参数值
function GetParameterValue(const PName:string):Extended; //得到参数值
Function GetParameterCount():integer; //得到参数的总数目
procedure GetParameterList(var PList:array of TParameterList); //返回参数列表
function IfHaveParameter(const PName:string):boolean;overload; //测试参数是否已经存在
function IfHaveParameter(const dValue:Extended;var cName:string):boolean;overload;//测试常数是否已经存在 并返回常数名称
function GetError():string; //返回错误描述
Function GetExeCodeLength():integer; //返回编译以后的程序指令区代码长度(字节)
Function GetExeParameterLength():integer; //返回编译以后的程序数据区代码长度(字节)
private
{ Private declarations }
{略}
public
{ Public declarations }
constructor Create();
destructor Destroy();Override;
end;
{由于代码实现太长,具体代码略}