include "enable_io.s7i";
include "float.s7i";
include "math.s7i";
const type: complex is new object struct
var float: re is 0.0;
var float: im is 0.0;
end struct;
const func complex: complex (in float: re, in float: im) is func
result
var complex: aComplex is complex.value;
begin
aComplex.re := re;
aComplex.im := im;
end func;
const func complex: complex (in float: re) is func
result
var complex: aComplex is complex.value;
begin
aComplex.re := re;
aComplex.im := 0.0;
end func;
const func complex: polar (in float: magnitude, in float: angle) is func
result
var complex: aComplex is complex.value;
begin
aComplex.re := magnitude * cos(angle);
aComplex.im := magnitude * sin(angle);
end func;
const func complex: complex (in integer: re) is func
result
var complex: aComplex is complex.value;
begin
aComplex.re := flt(re);
aComplex.im := 0.0;
end func;
const func complex: (attr complex) conv (in integer: re) is func
result
var complex: aComplex is complex.value;
begin
aComplex.re := flt(re);
aComplex.im := 0.0;
end func;
const func complex: (attr complex) conv (in float: re) is func
result
var complex: aComplex is complex.value;
begin
aComplex.re := re;
aComplex.im := 0.0;
end func;
const func boolean: (ref complex: number1) = (ref complex: number2) is
return number1.re = number2.re and number1.im = number2.im;
const func boolean: (ref complex: number1) <> (ref complex: number2) is
return number1.re <> number2.re or number1.im <> number2.im;
const func complex: + (in complex: number) is
return number;
const func complex: - (in complex: number) is func
result
var complex: negatedNumber is complex.value;
begin
negatedNumber.re := -number.re;
negatedNumber.im := -number.im;
end func;
const func complex: conj (in complex: number) is func
result
var complex: conjugate is complex.value;
begin
conjugate.re := number.re;
conjugate.im := -number.im;
end func;
const func complex: (in complex: summand1) + (in complex: summand2) is func
result
var complex: sum is complex.value;
begin
sum.re := summand1.re + summand2.re;
sum.im := summand1.im + summand2.im;
end func;
const func complex: (in complex: minuend) - (in complex: subtrahend) is func
result
var complex: difference is complex.value;
begin
difference.re := minuend.re - subtrahend.re;
difference.im := minuend.im - subtrahend.im;
end func;
const func complex: (in complex: factor1) * (in complex: factor2) is func
result
var complex: product is complex.value;
begin
product.re := factor1.re * factor2.re - factor1.im * factor2.im;
product.im := factor1.re * factor2.im + factor1.im * factor2.re;
end func;
const func complex: (in complex: dividend) / (in complex: divisor) is func
result
var complex: quotient is complex.value;
local
var float: common_divisor is 0.0;
begin
common_divisor := divisor.re * divisor.re + divisor.im * divisor.im;
quotient.re := (dividend.re * divisor.re + dividend.im * divisor.im) / common_divisor;
quotient.im := (dividend.im * divisor.re - dividend.re * divisor.im) / common_divisor;
end func;
const proc: (inout complex: number) +:= (in complex: delta) is func
begin
number.re +:= delta.re;
number.im +:= delta.im;
end func;
const proc: (inout complex: number) -:= (in complex: delta) is func
begin
number.re -:= delta.re;
number.im -:= delta.im;
end func;
const proc: (inout complex: number) *:= (in complex: factor) is func
local
var float: real_part is 0.0;
begin
real_part := number.re * factor.re - number.im * factor.im;
number.im := number.re * factor.im + number.im * factor.re;
number.re := real_part;
end func;
const proc: (inout complex: number) /:= (in complex: divisor) is func
local
var float: common_divisor is 0.0;
var float: real_part is 0.0;
begin
common_divisor := divisor.re * divisor.re + divisor.im * divisor.im;
real_part := (number.re * divisor.re + number.im * divisor.im) / common_divisor;
number.im := (number.im * divisor.re - number.re * divisor.im) / common_divisor;
number.re := real_part;
end func;
const func float: abs (in complex: number) is
return sqrt(number.re ** 2 + number.im ** 2);
const func float: sqrAbs (in complex: number) is
return number.re ** 2 + number.im ** 2;
const func float: arg (in complex: number) is
return atan2(number.im, number.re);
const func complex: (in complex: base) ** (in integer: exponent) is func
result
var complex: power is complex.value;
local
var float: r is 0.0;
var float: phi is 0.0;
begin
r := abs(base) ** exponent;
phi := arg(base) * flt(exponent);
power.re := r * cos(phi);
power.im := r * sin(phi);
end func;
const func integer: compare (in complex: number1, in complex: number2) is func
result
var integer: signumValue is 0;
begin
signumValue := compare(number1.re, number2.re);
if signumValue = 0 then
signumValue := compare(number1.im, number2.im);
end if;
end func;
const func integer: hashCode (in complex: num) is
return hashCode(num.re) mod 16#40000000 + hashCode(num.im) mod 16#40000000;
const func string: str (in complex: number) is func
result
var string: stri is "";
begin
stri := str(number.im) <& "i";
if stri[1] = '-' then
stri := str(number.re) & stri;
else
stri := str(number.re) & "+" & stri;
end if;
end func;
const func complex: complex (in string: stri) is func
result
var complex: aComplex is complex.value;
local
var integer: pos is 0;
var integer: pos2 is 0;
begin
pos := rpos(stri, '+');
pos2 := rpos(stri, '-');
if pos2 > pos then
pos := pos2;
end if;
if pos <> 0 and stri[length(stri)] = 'i' then
aComplex.re := float(stri[.. pred(pos)]);
aComplex.im := float(stri[pos .. pred(length(stri))]);
else
raise RANGE_ERROR;
end if;
end func;
const func complex: (attr complex) parse (in string: stri) is
return complex(stri);
const func string: (in complex: number) digits (in integer: precision) is func
result
var string: stri is "";
begin
stri := number.im digits precision <& "i";
if stri[1] = '-' then
stri := number.re digits precision <& stri;
else
stri := number.re digits precision <& "+" <& stri;
end if;
end func;
const func string: (in complex: number) sci (in integer: precision) is func
result
var string: stri is "";
begin
stri := number.im sci precision <& "i";
if stri[1] = '-' then
stri := number.re sci precision <& stri;
else
stri := number.re sci precision <& "+" <& stri;
end if;
end func;
enable_io(complex);
DECLARE_TERNARY(complex);