unit dequation;

interface

uses
  dmath;

// A*x + B*y = C
// D*x + E*y = F
function Solve2LinearEquations2i(A, B, C, D, E, F: LongInt; out X, Y: Single): Boolean;
function Solve2LinearEquations2f(A, B, C, D, E, F: Single; out X, Y: Single): Boolean;
function Solve2LinearEquations2d(A, B, C, D, E, F: Double; out X, Y: Double): Boolean;

function Discriminanti(A, B, C: LongInt): LongInt; inline; overload;
function Discriminantf(A, B, C: Single): Single; inline; overload;
function Discriminantd(A, B, C: Double): Double; inline; overload;
function Discriminanti(B, C: LongInt): LongInt; inline; overload;
function Discriminantf(B, C: Single): Single; inline; overload;
function Discriminantd(B, C: Double): Double; inline; overload;

//   x^2 + B*x + C = 0
function SolveSqEquationi(   B, C: LongInt; out X1, X2: Single): LongInt; overload;
function SolveSqEquationf(   B, C: Single; out X1, X2: Single): LongInt; overload;
function SolveSqEquationd(   B, C: Double; out X1, X2: Double): LongInt; overload;
// A*x^2 + B*x + C = 0
function SolveSqEquationi(A, B, C: LongInt; out X1, X2: Single): LongInt; overload; inline;
function SolveSqEquationf(A, B, C: Single; out X1, X2: Single): LongInt; overload; inline;
function SolveSqEquationd(A, B, C: Double; out X1, X2: Double): LongInt; overload; inline;

implementation

function Solve2LinearEquations2i(A, B, C, D, E, F: LongInt; out X, Y: Single): Boolean;
var
  Det: LongInt;
begin
  Det := B*D - A*E;
  Result := Det <> 0;
  if Result then begin
    X := (D*C - A*F) / Det;
    Y := (B*F - C*E) / Det;
  end;
end;

function Solve2LinearEquations2f(A, B, C, D, E, F: Single; out X, Y: Single): Boolean;
var
  Det: Single;
begin
  Det := B*D - A*E;
  //Write(Det, ' ');
  Result := Abs(Det) > EPS;
  if Result then begin
    X := (B*F - E*C) / Det;
    Y := (D*C - A*F) / Det;
  end;
  //Write(Result, ' ', Round(X), ' ', Round(Y), ' ');
end;

function Solve2LinearEquations2d(A, B, C, D, E, F: Double; out X, Y: Double): Boolean;
var
  Det: Double;
begin
  Det := B*D - A*E;
  Result := Abs(Det) > EPS;
  if Result then begin
    X := (D*C - A*F) / Det;
    Y := (B*F - C*E) / Det;
  end;
end;

function Discriminanti(A, B, C: LongInt): LongInt;
begin
  Result := B*B - 4*A*C;
end;

function Discriminantf(A, B, C: Single): Single;
begin
  Result := B*B - 4*A*C;
end;

function Discriminantd(A, B, C: Double): Double;
begin
  Result := B*B - 4*A*C;
end;

function Discriminanti(B, C: LongInt): LongInt;
begin
  Result := B*B - 4*C;
end;

function Discriminantf(B, C: Single): Single;
begin
  Result := B*B - 4*C;
end;

function Discriminantd(B, C: Double): Double;
begin
  Result := B*B - 4*C;
end;

function SolveSqEquationi(   B, C: LongInt; out X1, X2: Single): LongInt;
var
  D: LongInt;
  S: Single;
begin
  D := Discriminanti(B, C);
  if D = 0 then begin
    Result := 1;
    X1 := -B / 2;
    X2 := X1;
  end else if D > 0 then begin
    Result := 2;
    S := Sqrt(D);
    X1 := (-B - S) / 2;
    X2 := (-B + S) / 2;
  end else
    Result := 0;
end;

function SolveSqEquationf(   B, C: Single; out X1, X2: Single): LongInt;
var
  D: Single;
begin
  D := Discriminantf(B, C);
  if Abs(D) < EPS then begin
    Result := 1;
    X1 := -B / 2;
    X2 := X1;
  end else if D > 0 then begin
    Result := 2;
    D := Sqrt(D);
    X1 := (-B - D) / 2;
    X2 := (-B + D) / 2;
  end else
    Result := 0;
end;

function SolveSqEquationd(   B, C: Double; out X1, X2: Double): LongInt;
var
  D: Double;
begin
  D := Discriminantd(B, C);
  if Abs(D) < EPS then begin
    Result := 1;
    X1 := -B / 2;
    X2 := X1;
  end else if D > 0 then begin
    Result := 2;
    D := Sqrt(D);
    X1 := (-B - D) / 2;
    X2 := (-B + D) / 2;
  end else
    Result := 0;
end;

function SolveSqEquationi(A, B, C: LongInt; out X1, X2: Single): LongInt;
var
  D: LongInt;
  S, A2: Single;
begin
  if A = 0 then begin
    if B = 0 then
      Exit(0);
    Result := 1;
    X1 := - C / B;
    X2 := X1;
    Exit(1);
  end;

  D := Discriminanti(A, B, C);
  if D = 0 then begin
    Result := 1;
    X1 := -B / (2 * A);
    X2 := X1;
  end else if D > 0 then begin
    Result := 2;
    S := Sqrt(D);
    A2 := -2 * A;
    X1 := (B - S) / A2;
    X2 := (B + S) / A2;
  end else
    Result := 0;
end;

function SolveSqEquationf(A, B, C: Single; out X1, X2: Single): LongInt;
var
  D, A2: Single;
begin
  if Abs(A) < EPS then begin
    if Abs(B) < EPS then
      Exit(0);
    X1 := - C / B;
    X2 := X1;
    Exit(1);
  end;

  D := Discriminantf(A, B, C);
  if D = 0 then begin
    Result := 1;
    X1 := -B / (2 * A);
    X2 := X1;
  end else if D > 0 then begin
    Result := 2;
    D := Sqrt(D);
    A2 := -2 * A;
    X1 := (B - D) / A2;
    X2 := (B + D) / A2;
  end else
    Result := 0;
end;

function SolveSqEquationd(A, B, C: Double; out X1, X2: Double): LongInt;
var
  D, A2: Double;
begin
  if Abs(A) < EPS then begin
    if Abs(B) < EPS then
      Exit(0);
    X1 := - C / B;
    X2 := X1;
    Exit(1);
  end;

  D := Discriminantd(A, B, C);
  if D = 0 then begin
    Result := 1;
    X1 := -B / (2 * A);
    X2 := X1;
  end else if D > 0 then begin
    Result := 2;
    D := Sqrt(D);
    A2 := -2 * A;
    X1 := (B - D) / A2;
    X2 := (B + D) / A2;
  end else
    Result := 0;
end;


end.
