program LongMultiDemo;
{$mode objfpc}{$H+}
{ Multiply Two Long Numbers
------------------------------------
Implements manual big‑integer multiplication
using decimal strings.
}
(* Multiply two integer strings a * b and return the result as a string.
Caller receives a normal Pascal string.
No aliasing issues because strings are value types. *)
function LongMulti(const A, B: string): string;
var
a2, b2: string;
sign: Boolean;
la, lb: Integer;
digits: array of Integer;
i, j, pos, sum: Integer;
function TrimLeftSpaces(const s: string): string;
var
k: Integer;
begin
k := 1;
while (k <= Length(s)) and (s[k] = ' ') do
Inc(k);
Result := Copy(s, k, MaxInt);
end;
function StripLeadingZeros(const s: string): string;
var
k: Integer;
begin
k := 1;
while (k < Length(s)) and (s[k] = '0') do
Inc(k);
Result := Copy(s, k, MaxInt);
if Result = '' then
Result := '0';
end;
begin
(* Skip leading spaces *)
a2 := TrimLeftSpaces(A);
b2 := TrimLeftSpaces(B);
(* Handle sign *)
sign := False;
if (a2 <> '') and (a2[1] = '-') then
begin
sign := not sign;
Delete(a2, 1, 1);
end;
if (b2 <> '') and (b2[1] = '-') then
begin
sign := not sign;
Delete(b2, 1, 1);
end;
(* Skip leading zeros *)
a2 := StripLeadingZeros(a2);
b2 := StripLeadingZeros(b2);
(* If either is "0", return "0" *)
if (a2 = '0') or (b2 = '0') then
begin
Result := '0';
Exit;
end;
la := Length(a2);
lb := Length(b2);
(* Initialize result buffer with zeros *)
SetLength(digits, la + lb);
for i := 0 to High(digits) do
digits[i] := 0;
(* Multiply from right to left *)
for i := la downto 1 do
begin
if not (a2[i] in ['0'..'9']) then
Continue;
for j := lb downto 1 do
begin
if not (b2[j] in ['0'..'9']) then
Continue;
pos := (i - 1) + (j - 1) + 1; (* zero-based array index *)
sum := digits[pos] + (Ord(a2[i]) - Ord('0')) * (Ord(b2[j]) - Ord('0'));
digits[pos] := sum mod 10;
digits[pos - 1] := digits[pos - 1] + (sum div 10);
end;
end;
(* Convert digits[] to string, skipping leading zero *)
Result := '';
i := 0;
if digits[0] = 0 then
i := 1;
while i < Length(digits) do
begin
Result := Result + Chr(digits[i] + Ord('0'));
Inc(i);
end;
(* Add sign if needed *)
if sign then
Result := '-' + Result;
end;
begin
WriteLn(
LongMulti(
' 18361891827367132321',
'-18361891827367132321'
)
);
end.
(*
run:
-337159071479931885857929667075122847041
*)