library LongInt; var buffer: string; // [1, -1] <==> [a >= 0, a < 0] function Sign(a: PChar): integer; begin if a[0] = '-' then result := -1 else result := 1; end; // |a| function Abs(a: PChar): PChar; begin if a[0] = '-' then result := @a[1] else result := a; end; // [1, 0, -1] <==> [a > b, a = b, a < b] (a,b >= 0) function Greater(a, b: PChar): integer; var i, j: integer; begin i := Length(a); j := Length(b); if (i > j) then result := 1 else if (i < j) then result := -1 else begin i := 0; while (i < j) and (a[i] = b[i]) do inc(i); if i = j then result := 0 else if a[i] > b[i] then result := 1 else result := -1; end; end; // pobrisemo odvecne nicle na zacetku stevila procedure makeShort(var a: string); var i, j: integer; begin i := 1; j := Length(a); while (i < j) and (a[i] = '0') do inc(i); if (i > 1) then Delete(a, 1, i - 1); end; // a + b (a,b >= 0) function Sum(a, b: PChar): string; var i, j: integer; sa, sb: integer; vs, carry: integer; begin result := ''; carry := 0; i := Length(a); j := Length(b); while (i > 0) or (j > 0) or (carry > 0) do begin dec(i); if i >= 0 then sa := ord(a[i]) - 48 else sa := 0; dec(j); if j >= 0 then sb := ord(b[j]) - 48 else sb := 0; vs := sa + sb + carry; carry := vs div 10; result := chr(vs mod 10 + 48) + result; end; end; // a - b (a >= b >= 0) function Sub(a, b: PChar): string; var i, j: integer; sa, sb: integer; vs, carry: integer; begin result := ''; carry := 0; i := Length(a); j := Length(b); while (i > 0) or (j > 0) or (carry > 0) do begin dec(i); if i >= 0 then sa := ord(a[i]) - 48 else sa := 0; dec(j); if j >= 0 then sb := ord(b[j]) - 48 else sb := 0; vs := sa - sb - carry; carry := ord(vs < 0); if vs < 0 then inc(vs, 10); result := chr(vs mod 10 + 48) + result; end; makeShort(result); end; // a * b (a >= 0, 0 <= b <= 9) function Times(a: Pchar; b: integer): string; var i: integer; sa: integer; vs, carry: integer; begin if b = 0 then result := '0' else begin result := ''; carry := 0; i := Length(a); while (i > 0) or (carry > 0) do begin dec(i); if i >= 0 then sa := ord(a[i]) - 48 else sa := 0; vs := sa * b + carry; carry := vs div 10; result := chr(vs mod 10 + 48) + result; end; end; makeShort(result); end; // a * b (a,b >= 0) function Prod(a, b: PChar): string; var i: integer; begin result := ''; for i := 0 to Length(b) - 1 do result := Sum(PChar(result + '0'), PChar(Times(a, ord(b[i]) - 48))); makeShort(result); end; // a div b (ce je rezultat majhen) function Division(a, b: PChar): integer; var s: string; begin s := a; result := 0; while Greater(PChar(s), b) >= 0 do begin s := Sub(PChar(s), b); inc(result); end; end; // a + b function LongSum(a, b: PChar): PChar; stdcall; var c: string; aa, bb: PChar; sa, sb, gr: integer; begin sa := Sign(a); aa := Abs(a); sb := Sign(b); bb := Abs(b); if sa = sb then begin c := Sum(aa, bb); if sa < 0 then c := '-' + c; end else begin gr := Greater(aa, bb); if gr = 0 then c := '0' else if gr > 0 then begin c := Sub(aa, bb); if sa < 0 then c := '-' + c; end else begin c := Sub(bb, aa); if sb < 0 then c := '-' + c; end; end; buffer := c; result := PChar(buffer); end; // a - b function LongSub(a, b: PChar): PChar; stdcall; var c: string; aa, bb: PChar; sa, sb, gr: integer; begin sa := Sign(a); aa := Abs(a); sb := Sign(b); bb := Abs(b); if sa <> sb then begin c := Sum(aa, bb); if sa < 0 then c := '-' + c; end else begin gr := Greater(aa, bb); if gr = 0 then c := '0' else if gr > 0 then begin c := Sub(aa, bb); if sa < 0 then c := '-' + c; end else begin c := Sub(bb, aa); if sb < 0 then c := '-' + c; end; end; buffer := c; result := PChar(buffer); end; // a * b function LongProd(a, b: PChar): PChar; stdcall; var c: string; begin c := Prod(Abs(a), Abs(b)); if Sign(a) <> Sign(b) then c := '-' + c; buffer := c; result := PChar(buffer); end; // a div b function LongDiv(a, b: PChar): PChar; stdcall; var s, c: string; aa, bb: PChar; sa, sb: integer; i, n, d: integer; begin sa := Sign(a); aa := Abs(a); sb := Sign(b); bb := Abs(b); if bb = '0' then c := 'Division by 0' else if Greater(aa, bb) < 0 then c := '0' else begin s := ''; c := ''; i := 0; n := Length(aa); while i < n do begin s := s + aa[i]; makeShort(s); d := Division(PChar(s), bb); c := c + Chr(d + 48); s := Sub(PChar(s), PChar(Times(bb, d))); inc(i); end; makeShort(c); if sa * sb < 0 then c := '-' + c; end; buffer := c; result := PChar(buffer); end; // a mod b function LongMod(a, b: PChar): PChar; stdcall; var s, c: string; aa, bb: PChar; sa: integer; i, n, d: integer; begin sa := Sign(a); aa := Abs(a); bb := Abs(b); if bb = '0' then c := 'Division by 0' else if Greater(aa, bb) < 0 then c := a else begin s := ''; c := ''; i := 0; n := Length(aa); while i < n do begin s := s + aa[i]; makeShort(s); d := Division(PChar(s), bb); c := c + Chr(d + 48); s := Sub(PChar(s), PChar(Times(bb, d))); inc(i); end; makeShort(s); c := s; if sa < 0 then c := '-' + c; end; buffer := c; result := PChar(buffer); end; // a^n (n >= 0) function LongPower(a: PChar; n: word): PChar; stdcall; var b, c: string; begin b := a; c := '1'; while n > 0 do begin if n mod 2 = 1 then c := LongProd(PChar(c), PChar(b)); b := LongProd(PChar(b), PChar(b)); n := n div 2; end; buffer := c; result := PChar(buffer); end; exports LongSum, LongSub, LongProd, LongDiv, LongMod, LongPower; begin end.