using System;
namespace Freya.Demos;
public
// An immutable structure.
Complex = const record
public
constructor(Re, Im: Double);
property Re, Im: Double; readonly;
property R: Double => (Re.Sqr + Im.Sqr).Sqrt;
method ToString: String; override;
method Equals(Other: Object): Boolean; override;
method GetHashCode: Integer; override;
public
// Predefined complex constants.
static Zero: Complex = new Complex; readonly;
static One: Complex = new Complex(1, 0); readonly;
static I: Complex = new Complex(0, 1); readonly;
method=(c1, c2: Complex): Boolean =>
c1.Re = c2.Re and c1.Im = c2.Im;
method<>(c1, c2: Complex): Boolean =>
c1.Re <> c2.Re or c1.Im <> c2.Im;
method-(c: Complex) => new Complex(-c.Re, -c.Im);
method+(c1, c2: Complex) =>
new Complex(c1.Re + c2.Re, c1.Im + c2.Im);
method-(c1, c2: Complex) =>
new Complex(c1.Re - c2.Re, c1.Im - c2.Im);
method*(c1, c2: Complex) =>
new Complex(
c1.Re * c2.Re - c1.Im * c2.Im,
c1.Re * c2.Im + c1.Im * c2.Re);
method/(c1, c2: Complex) =>
using r2 := c2.R.Sqr do
new Complex(
(+c1.Re * c2.Re + c1.Im * c2.Im) / r2,
(-c1.Re * c2.Im - c1.Im * c2.Re) / r2);
operator Explicit(C: Complex): Double => C.Re;
operator Implicit(Value: Integer) => new Complex(Value, 0);
operator Implicit(Value: Double) => new Complex(Value, 0);
end;
implementation for Complex is
constructor(Re, Im: Double);
begin
Self.Re := Re;
Self.Im := Im;
end;
method ToString: String;
begin
if Im = 0.0 then
Result := Re.ToString
else if Re = 0.0 then
if Im = 1.0 then
Result := "i"
else
Result := Im.ToString + "i"
else if Im = 1.0 then
Result := String.Format("<{0}+i>", Re)
else
Result := String.Format('<{0}+{1}i>', Re, Im);
end;
method Equals(Other: Object): Boolean;
// Click here for the compiled IL code!
begin
if Other <> nil and Other.GetType = Complex then
begin
var c := Complex(Other);
Result := Re = c.Re and Im = c.Im;
end
else
Result := false;
end;
method GetHashCode: Integer =>
Re.GetHashCode xor Im.GetHashCode;
end.