📄 compilecomplex_hss.pas
字号:
unit CompileComplex_Hss;
//////////////////////////////////////////////////////////////////////////
// //
// 复数函数动态编译器TCompileComplex类 //
// 作者:侯思松 2002.8-2002.11 //
// 有改进意见或发现任何错误请转告我,本人不胜感激。 //
// E-Mail:HouSisong@263.net //
// ( 转载时请保留本说明:) ) //
// //
//////////////////////////////////////////////////////////////////////////
///>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>///
/// <<功能简介>>: ///
/// TCompileComplex可以在程序运行过程中动态完成复数函数表达式字符串的 ///
/// 编译执行,(可以带复数参数;动态生成机器码执行,不是解释执行)执行速度超快!! ///
///<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<///
{
<<使用方法>>:
uses
CompileComplex_Hss, Complex_Hss, ...;
var
Compilation : TCompileComplex; // 声明Compilation为复数函数动态编译器TCompileComplex类的实例
PComplexX : PTComplex;
PComplexY : PTComplex;
xValue : TComplex;
PList : TParameterListCmCx;
begin
Compilation:=TCompileComplex.Create; //创建类
try
Compilation.SetText(str); //str为要 求值的复数表达式字符串,比如str:='i-x*(2.5+3*i)-sin(y*i*PI/2)'
//(可以带有未知复数参数);
......
//如果有参数,可以获得参数地址,并赋值 (默认值为0)
//如: PComplexX:=Compilation.GetParameterAddress('x');
//如: PComplexY:=Compilation.GetParameterAddress('y');
// if not(PComplexX=nil) then PComplexA^:=CreateTComplex(1.5,3.2);
// if not(PComplexY=nil) then PComplexA^:=CreateTComplex(0.5,-1.0);
//也可以一次获得所有的参数列表:Compilation.GetParameterList(PList);
......
//for i:=0 to 10000-1 do
//begin
//更改参数值 ...
xValue:=Compilation.GetValue(); //获得表达式的值,
... //可以多次改变参数值并多次调用,这样才能显示出效率:)
//end;
ShowMessage(TComplexToStr(xValue));
......
finally
Compilation.Free; //释放类
end;
end;
}
interface
uses SysUtils,Forms, Classes, Math, Variants, Complex_Hss;
(*
//2002.11
简要声明:
任何用户使用本软件属于个人自愿选择,作者不会对用户使用本软件所引起
的对用户的任何形式的损失负责,作者也不承诺提供对本类的维护和服务等义务。
本类可以自由拷贝和使用,但必须包含完整的代码和说明,任何修改和用
于商业化目的的行为都应该尽量与作者取得联系,并得到授权。
( E-Mail: HouSisong@263.net )
本类的编写目的只是在程序运行过程中能够多次的快速的执行用户输入的
数学表达式,程序优化的目标是速度和高精度,所以基本数据类型采用的是80
位浮点型,很多地方的处理是以速度为首要目标,这样在计算的准确性和错误
处理方面就有所损失。
测试环境包括:Windows95、WindowsMe、Windows2000、WindowsXP。
测试过的CPU包括:奔腾、赛扬A、奔腾3、赛扬2、奔腾4。
*)
{
-----------------------------------------------------------------------------
不知道本TCompileComplex类单元在Linux环境下能不能用,作者没有试过,希望有大虾帮忙告知:)
希望大家能帮忙测试一下本编译类,特别是当把它用到了某些关键性计算事务中时,这
非常关键!一个小的bug就足以致命!!!您可以就某些方面进行测试,甚至是其中的一个函数,
然后把发现的错误的具体情况告诉我,以便修改;测试时没有发现错误也把测试情况告诉我,
万分感谢!!!
我的 E-Mail: HouSisong@263.net QQ: 9043542
------------------------------------------------------------------------------
//2002.8
}
(*
<<详细说明>>:
0.支持复数函数表达式的编译执行;
1.支持带复数参数编译,参数默认值为0+0*i;运行前请赋值;
2.常数可以用科学计数法表示,如: -1.4E-4=-0.00014;
系统定义的常量: 圆周率 PI=3.1415926535897932384626433832795...
逻辑真 true=1
逻辑假 false=0
当标识符为e时,系统默认值为 自然数
即 e=2.7182818284590452353602874713527...
但它和PI,true,false不同,e可以重新赋值, pi,true,false是系统常量,e是用户变量
3.使用多重括号并不会降低速度,特别是在不容易分清楚计算优先级的时候,请多使用括号;
4.表达式中函数名和参数名等不区分大小写;关键字中不允许插入空格等字符;
5.编译的文本长度几乎不受限制(只是受内存和编译时间等系统影响)
6.利用错误号功能可以将错误描述翻译为其他语言(给出了两个翻译例子:中文繁体BIG5码的错误描述和英文版的错误描述);
7.允许在表达式中使用注释(TCompileComplex.EnabledNote:=true;),注释写法为:
单行注释: 双斜杠// 开始到一行结束(即遇到回车换行符)
长段注释: '{'、'}' 或'/*'、'*/' 之间的部分
8.系统使用的标识符除去下面列出的函数名(包括别名)外还有 :
'PI'、'true'、'false'、'TCmCxSYS_IF_?'、'TCmCxSYS_Boolean??'、'TCmCxSYS_Const_*' 和 'TCmCxSYS_Function_i' 等,
自定义的标识符名称请不要再次使用它们; (即前缀不能为'TCmCxSYS_')
9.支持的复数函数:
这里的实数域为: R' , R'约为 (-1.1E+4932,-3.6E-4951) and [ 0 ] and (+3.6E-4951,+1.1E+4932)
当实数属于(+-3.6E-4951,0) 时认为实数等于0
复数的实部和虚部分别属于以上实数域R'
以下形参Z,Z1,Z2没有特别指明都属于复数;
x属于实数(或为复数时虚部为零(不为零时忽略虚部))
N为整数(N为小数时也进行同样的计算,或为复数时虚部为零(不为零时忽略虚部))
(函数计算的结果和中间结果也不能超出实数域 R')
算符(函数)名称 书写格式和变量取值范围 说明
+ 加法 Z1+Z2 或者: Add(Z1,Z2)
- 减法 Z1-Z2 或者: Sub(Z1,Z2)
* 乘法 Z1*Z2 或者: Mul(Z1,Z2)
/ 除法 Z1/Z2 或者: Div(Z1,Z2) ; Z2<>0+0*i
^ 指数 Z1^Z2 或者: Power(Z1,Z2)、Z1**Z2 Z1^Z2
PowerX 指数 PowerX(Z,x) Z^x
XPower 指数 XPower(x,Z) x^Z
;复数参加布尔运算时就只考虑复数的实部
;比较运算产生的结果为逻辑值(真或假),即结果只可能为1或0
= 等于 x=y (2=3-1) =true =1
<> 不等于 x<>y (2<>3-1) =false =0
< 小于 x<y (2<3) =true
> 大于 x>y (2>3) =false
<= 小于等于 x<=y (Abs(Z)>=0) =true
>= 大于等于 x>=y (3>=PI) =false
;逻辑运算中 实部0表示 假(false),实部非0会被当作 真(true)来参加逻辑运算
;用大写X,Y表示逻辑值 (注意必须写扩号)
ADD 逻辑与 (X) ADD (Y) (1>2) AND (true)=false
OR 逻辑或 (X) OR (Y) (false) OR (true)=true
XOR 逻辑异或 (X) XOR (Y) (true) XOR (true)=false
NOT 逻辑非 NOT (X) NOT (1)=false
Sqr 平方 Sqr(Z) 注意平方和开方的函数名称
Sqr2Z 平方+ Sqr2Z(Z) Z^2+Z
Sqr3 立方 Sqr3(Z)
Sqr4 四方 Sqr4(Z)
Sqrt 开方 Sqrt(Z)
SqrtN 开N次方 SqrtN(Z,N) Z^(1/N)
Exp 自然指数 Exp(Z)
Ln 自然对数 Ln(Z)
Log2 2的对数 Log2(Z)
Log10 10的对数 Log10(Z) 或者: Log(Z)
LogN N的对数 LogN(N,Z)
Int 取整 Int(Z) 或者: Floor(Z) (向负穷大取整)
Trunc 截断取整 Trunc(Z) (向零取整)
Round 四舍五入 Round(Z) (四舍五入取整)
Ceil 舍入取整 Ceil(Z) (向正穷大取整)
Max 最大值函数 Max(Z1,Z2) (返回复数绝对值最大的复数)
Min 最小值函数 Min(Z1,Z2) (返回复数绝对值最小的复数)
MaxX 最大值函数 MaxX(Z1,Z2) (返回实部值最大的复数)
MinX 最小值函数 MinX(Z1,Z2) (返回实部值最小的复数)
Real 求实部 Real(Z)
Imag 求虚部 Imag(Z)
Abs 绝对值 Abs(Z) |Z|
AbsSqr 绝对值平方 AbsSqr(Z) |Z|^2=x*x+y*y
Arg 求复角 Arg(Z) 或: Angle(Z) 值属于 -PI~PI
FromPolar极坐标到复数FromPolar(Z) 参数为极坐标 x=Z.x*Cos(Z.y) ; y:=Z.x*Sin(Z.y) ;
ToPolar 复数到极坐标ToPolar(Z) x:=Sqrt(Z.x*Z.x+Z.y*Z.y) ; y:=ArcTan2(Z.y,Z.x);
Conj 求共轭 Conj(Z)
FLip 虚实交换 FLip(Z)
Unity 归一化 Unity(Z) Z/|Z|
Distance 距离 Distance(Z1,Z2) |Z1-Z2|
Rev 倒数 Rev(Z)
Sgn 符号函数 Sgn(Z)
Random 随机函数 Random(Z) 或者:RND(Z)、Rand(Z)
(要产生真正的随机数,而不是固定随机数序列,请在创建或编译完成后
取得表达式值之前调用一次TCompileComplex.SetRandomize();函数。)
Sin 正弦 Sin(Z)
Cos 余弦 Cos(Z)
Tan 正切 Tan(Z) 或者: tg(Z)
ArcSin 反正弦 ArcSin(Z)
ArcCos 反余弦 ArcCos(Z)
ArcTan 反正切 ArcTan(Z) 或者: Arctg(Z)
Cot 余切 Cot(Z) 或者: Ctg(Z) Cot(Z)=1/Tan(Z)
Sec 正割 Sec(Z) Sec(Z)=1/Cos(Z)
Csc 余割 Csc(Z) Csc(Z)=1/Sin(Z)
ArcCot 反余切函数 ArcCot(Z) 或者: ArcCtg(Z) ArcCot(Z)=ArcTan(1/Z)
ArcSec 反正割函数 ArcSec(Z) ArcSec(Z)=ArcCos(1/Z)
ArcCsc 反余割函数 ArcCsc(Z) ArcCsc(Z)=ArcSin(1/Z)
SinH 双曲正弦 SinH(Z)
CosH 双曲余弦 CosH(Z)
TanH 双曲正切 TanH(Z) 或者: tgH(Z)
ArcSinH 反双曲正弦 ArcSinH(Z)
ArcCosH 反双曲余弦 ArcCosH(Z)
ArcTanH 反双曲正切 ArcTanH(Z) 或者: ArctgH(Z)
CotH 双曲余切 CotH(Z) 或者: CtgH(Z)
SecH 双曲正割 SecH(Z)
CscH 双曲余割 CscH(Z)
ArcCotH 反双曲余切函数 ArcCotH(Z) 或者: ArcCtgH(Z)
ArcSecH 反双曲正割函数 ArcSecH(Z)
ArcCscH 反双曲余割函数 ArcCscH(Z)
If 条件函数 If(s,r1,r2) If(True,2,3)=2; If(0,2,3)=3;
(等价于高级语言的: If (s) Then Result:=r1 Else Result:=r2;)
10. 运算符优先级表:
由高到低
() (包括各种函数)
^
* \ / mod
+ -
= <> < > <= >=
AND、OR、XOR(NOT 可以看作函数)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -