📄 complex_hss.pas
字号:
{begin
result := Trunc(X);
if Frac(X) < 0 then
result:=result-1;
}
var
temp1,temp2: word;
asm
fld x
FNSTCW temp1 // 保存协处理器控制字,用来恢复
FNSTCW temp2 // 保存协处理器控制字,用来修改
FWAIT
OR temp2, 0700H // 使RC场向负无穷大取整 //必须保证 RC=00 然后改为 RC=01
FLDCW temp2 // 载入协处理器控制字,RC场已经修改
FRNDINT
FWAIT
FLDCW temp1 // 恢复协处理器控制字
end;
function Ceil(const X: CmxFloat): CmxFloat; register;assembler {取整,大于x的最小整数}
{begin
result := Trunc(X);
if Frac(X) > 0 then
result:=result+1; }
var
temp1,temp2: word;
asm
fld x
FNSTCW temp1 // 保存协处理器控制字,用来恢复
FNSTCW temp2 // 保存协处理器控制字,用来修改
FWAIT
OR temp2, 0B00H // 使RC场向正无穷大取整 //必须保证 RC=00 然后改为 RC=10
FLDCW temp2 // 载入协处理器控制字,RC场已经修改
FRNDINT
FWAIT
FLDCW temp1 // 恢复协处理器控制字
end;
//==============================================================================
{实数和复数转换函数}
Function CreateTComplex(const X: CmxFloat;const Y: CmxFloat): TComplex;{Z:=x+y*i}
Begin
result.x:=X;
result.y:=Y;
End;
Function CreateTComplex(const X: CmxFloat): TComplex;{Z:=x+0*i}
Begin
result.x:=X;
result.y:=0;
End;
Function CreateTComplexR(const R: CmxFloat;const Arg: CmxFloat):TComplex;register;assembler{Z:=r*e^(Arg*i)}
{Begin
result.x:=r*Cos(Arg);
result.y:=r*Sin(Arg); }
asm
fld Arg
fsincos
fld R
fmul st(2),st
fmulp st(1),st
fstp CmxFloat [eax]//result.x
fstp CmxFloat [eax+FloatByte]//result.y
End;
function GetTComplex_R(const Z1:TComplex):CmxFloat;register;assembler {R:=|Z1|=(Z1.x*Z1.x+Z1.y*Z1.y)^0.5}
{begin
result:=sqrt(sqr(Z1.x)+sqr(Z1.y));
}
asm
fld CmxFloat [eax+FloatByte]//Z1.y
fld CmxFloat [eax]//Z1.x
fmul st,st(0)
fxch st(1)
fmul st,st(0)
faddp st(1),st
fsqrt
end;
Procedure GetTComplex_RV(var Z1:TComplex); register;assembler{Z1.x:=|Z1|,Z1.y:=0}
{begin
Z1.x:=sqrt(sqr(Z1.x)+sqr(Z1.y));
Z1.y:=0;}
asm
fld CmxFloat [eax+FloatByte]//Z1.y
fld CmxFloat [eax]//Z1.x
fmul st,st(0)
fxch st(1)
fmul st,st(0)
faddp st(1),st
fsqrt
fldz
fstp CmxFloat [eax+FloatByte]//Z1.y
fstp CmxFloat [eax]//Z1.x
end;
function GetTComplex_Arg(const Z1:TComplex):CmxFloat;register;assembler {Arg:=Arctg(Z.y/Z.x),(-PI~PI)}
{begin
result:=ArcTan2(Z1.y,Z1.x); }
asm
FLD CmxFloat [eax+FloatByte]//Z1.Y
FLD CmxFloat [eax]//Z1.X
FPATAN
End;
Procedure GetTComplex_ArgV(var Z1:TComplex); register;assembler{Z:=Arctg(Z.y/Z.x)}
{begin
Z1.x:=ArcTan2(Z1.y,Z1.x);
Z1.y:=0; }
asm
FLD CmxFloat [eax+FloatByte]//Z1.Y
FLD CmxFloat [eax]//Z1.X
FPATAN
fldz
Fstp CmxFloat [eax+FloatByte]//Z1.Y =0
Fstp CmxFloat [eax]//Z1.X
End;
function TComplexToStrBK (const Z1:TComplex):string;{TComplex => string , ( Str:='(x,y)' }
begin
result:='('+floattostr(Z1.x)+','+floattostr(Z1.y)+')';
end;
function TComplexToStri (const Z1:TComplex):string;{TComplex => string , ( Str:='x+y*i' ) }
begin
if Z1.y<0 then
result:=floattostr(Z1.x)+'-'+floattostr(-Z1.y)+'*i'
else
result:=floattostr(Z1.x)+'+'+floattostr(Z1.y)+'*i';
end;
function TComplexToStr(const Z1:TComplex):string;{TComplex => string , ( Str:='x+y*i'(简略) ) 默认 }
begin
if Z1.y<0 then
begin
if Z1.x<>0 then
begin
if (Z1.y<>-1.0) then
result:=floattostr(Z1.x)+'-'+floattostr(-Z1.y)+'*i'
else
result:=floattostr(Z1.x)+'-i';
end
else
begin
if (Z1.y<>-1.0) then
result:=floattostr(Z1.y)+'*i'
else
result:='-i';
end;
end
else if Z1.y>0 then
begin
if Z1.x<>0 then
begin
if Z1.y<>1.0 then
result:=floattostr(Z1.x)+'+'+floattostr(Z1.y)+'*i'
else
result:=floattostr(Z1.x)+'+i';
end
else
begin
if (Z1.y<>1.0) then
result:=floattostr(Z1.y)+'*i'
else
result:='i';
end;
end
else
begin
result:=floattostr(Z1.x);
end;
end;
function StrToTComplexi (const Str:string):TComplex;{string => TComplex , ( Str:='(x,y)' or Str:='x+y*i') }
{字符串到复数的变换,string => TComplex }
{ 函数并不进行语法检查,
正确的复数字符串格式将返回正确的复数值,
不正确的复数字符串格式返回值不确定 }
{支持的复数字符串格式:
'(x,y)' 、'x,y'
'x+y*i' 、'(x+y*i)' 、'x+yi' 、'x-y*i' 、'x-i*y' 、'y*i+x' ......
其中x,y的格式例如: 12.3456E-2 , -1.123
比如:str='-1.5+2.5i' }
var tmpStr1 :string;
tmpStr2 :string;
tmpStr3 :string;
tmpChar :char;
tmpLi :integer;
tmpLd :integer;
i :integer;
begin
try
//去除多余字符
tmpStr2:=Str;
tmpStr2:=uppercase(tmpStr2);
tmpStr1:='';
for i:=1 to length(tmpStr2) do
begin
tmpChar:= tmpStr2[i];
case tmpChar of
'0','1','2','3','4','5','6','7','8','9','.','E',',','I':
begin
tmpStr1:=tmpStr1+tmpChar;
end;
'D':
begin
tmpStr1:=tmpStr1+'E';
end;
'+','-':
begin
if i>1 then
begin
if (tmpStr2[i-1]='E') or (tmpStr2[i-1]='D') then
tmpStr1:=tmpStr1+tmpChar
else
begin
if length(tmpStr1)>0 then
begin
if tmpchar='+' then
tmpStr1:=tmpStr1+','
else //if tmpchar='-'
tmpStr1:=tmpStr1+',-';
end
else
begin
tmpStr1:=tmpStr1+tmpChar;
end;
end;
end
else
tmpStr1:=tmpStr1+tmpChar;
end;
//else case '(' , ')' , '*' , ' ' , #0 , ...... tmpStr1:=tmpStr1+'';
end;//end case
end;
//按 ,位置把字符串分为两段
tmpStr2:='0';
tmpLi:=length(tmpStr1);
for i:=1 to tmpLi do
begin
if tmpStr1[i]=',' then
begin
tmpStr2:=copy(tmpStr1,i+1,tmpLi-i);
tmpStr1:=copy(tmpStr1,1,i-1);
break;
end;
end;
//处理 +- i
if (tmpStr1='+I') then
tmpStr1:='+1I'
else if (tmpStr1='-I') then
tmpStr1:='-1I'
else if (tmpStr1='I') then
tmpStr1:='1I';
if (tmpStr2='+I') then
tmpStr2:='+1I'
else if (tmpStr2='-I') then
tmpStr2:='-1I'
else if (tmpStr2='I') then
tmpStr2:='1I';
//提取 i
tmpLi:=length(tmpStr1);
tmpLd:=length(tmpStr2);
for i:=1 to tmpLi do
begin
if tmpStr1[i]='I' then
begin
tmpStr3:=copy(tmpStr1,1,i-1)+copy(tmpStr1,i+1,tmpli-i);
tmpStr1:=tmpStr2;
tmpStr2:=tmpStr3;
break;
end;
end;
for i:=1 to tmpLd do
begin
if tmpStr2[i]='I' then
begin
tmpStr2:=copy(tmpStr2,1,i-1)+copy(tmpStr2,i+1,tmpld-i);
break;
end;
end;
result.x:=strtofloat(tmpStr1);
result.y:=strtofloat(tmpStr2);
except
result.x:=0;
result.y:=0;
end;
end;
function TComplexX (const x:CmxFloat):TComplex;{CmxFloat=> TComplex,Z.x:=x,Z.y:=0}
begin
result.x:=x;
result.y:=0;
end;
function TComplexY (const y:CmxFloat):TComplex;{CmxFloat=> TComplex,Z.y:=y,Z.x:=0}
begin
result.x:=0;
result.y:=y;
end;
function C_FromPolar (const Z:TComplex):TComplex;register;assembler //极坐标到复数
{begin
result.x:=Z.x*Cos(Z.y);
result.y:=Z.x*Sin(Z.y); }
asm
fld CmxFloat [eax+FloatByte]//Z.y
fsincos
fld CmxFloat [eax]//Z.x
fmul st(2),st
fmulp st(1),st
fstp CmxFloat [edx]//result.x
fstp CmxFloat [edx+FloatByte]//result.y
end;
Procedure C_FromPolarV (var Z:TComplex); register;assembler //极坐标到复数
{var
Temp:CmxFloat;
begin
Temp:=Z.x*Cos(Z.y);
Z.y:=Z.x*Sin(Z.y);
Z.x:=Temp;}
asm
fld CmxFloat [eax+FloatByte]//Z.y
fsincos
fld CmxFloat [eax]//Z.x
fmul st(2),st
fmulp st(1),st
fstp CmxFloat [eax]//result.x
fstp CmxFloat [eax+FloatByte]//result.y
end;
function C_ToPolar (const Z:TComplex):TComplex;register;assembler//复数到极坐标
{begin
result.x:=sqrt(Sqr(Z.x)+sqr(Z.y));
result.y:=ArcTan2(Z.y,Z.x); }
asm
fld CmxFloat [eax+FloatByte] // Z.y
fld CmxFloat [eax] // Z.x
fld st(1)
fld st(1)
fpatan
fxch st(2)
fmul st,st(0)
fxch st(1)
fmul st,st(0)
faddp st(1),st
fsqrt
fstp CmxFloat [edx]// result.x
fstp CmxFloat [edx+FloatByte] // result.y
end;
Procedure C_ToPolarV (var Z:TComplex); register;assembler //复数到极坐标
{var
Temp:CmxFloat;
begin
Temp:=sqrt(Sqr(Z.x)+sqr(Z.y));
Z.y:=ArcTan2(Z.y,Z.x);
Z.x:=Temp;}
asm
fld CmxFloat [eax+FloatByte] // Z.y
fld CmxFloat [eax] // Z.x
fld st(1)
fld st(1)
fpatan
fxch st(2)
fmul st,st(0)
fxch st(1)
fmul st,st(0)
faddp st(1),st
fsqrt
fstp CmxFloat [eax]// z.x
fstp CmxFloat [eax+FloatByte] // z.y
end;
//==============================================================================
{复数函数_加减}
function C_add (const Z1:TComplex;const Z2:TComplex):TComplex;{Z:=Z1+Z2}
begin
result.x := Z1.x + Z2.x ;
result.y := Z1.y + Z2.y ;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -