Skip to content
Alexander A. Maly edited this page Jan 29, 2019 · 1 revision

На вход программе подаётся положительное целое число, не превосходящее 100.
Вывести факториал это числа.
Реализация длинной арифметики через текстовые строки. Не слишком эффективная, но показаны простейшие техники работы со строками и символами, разные способы передачи параметров и возврата значений, использования утверждений.

цел D = 10

алг Factorial
нач
  цел x, i
  ввод x
  утв 0 < x <= 10000
  лит res = "1", xs = "1"
  нц для i от 2 до x
    addhere1(1, xs)
    res := mul(res, xs)
  кц
  reverse(res)
  вывод res, нс
кон

алг reverse(аргрез лит s)
нач
  цел a = 1, b
  сим c
  b := длин(s)
  нц пока a < b
    c := s[a]
    s[a] := s[b]
    s[b] := c
    a := a + 1
    b := b - 1
  кц
кон

алг лит цел2лит(цел n)
нач
  утв 0 <= n
  цел x
  лит res = ""
  x := n
  нц пока x > 0
    res := res + символ(mod(x, D) + код('0'))
    x := div(x, D)
  кц
  знач := res
кон

алг addhere1(цел x, аргрез лит b)
нач
  утв 0 <= x < D
  цел lb, carry, i, y, z, r
  если x = 0 то
    выход
  все
  carry := x
  lb := длин(b)

  нц для i от 1 до lb
    y := код(b[i]) - код('0')
    утв 0 <= y < D
    z := y + carry
    carry := div(z, D)
    r := mod(z, D)
    b[i] := символ(r + код('0'))
  кц при carry = 0

  если carry > 0 то
    b := b + символ(carry + код('0'))
  все
кон

алг addhere(лит a, цел shift, аргрез лит b)
нач
  утв 0 <= shift
  цел la, lb, carry = 0, i, x, y, z, r
  la := длин(a)
  lb := длин(b)
  нц пока lb < shift + la
    b := b + '0'
    lb := lb + 1
  кц
  нц для i от shift + 1 до shift + la
    x := код(a[i - shift]) - код('0')
    утв 0 <= x < D
    y := код(b[i]) - код('0')
    утв 0 <= y < D
    z := x + y + carry
    carry := div(z, D)
    r := mod(z, D)
    b[i] := символ(r + код('0'))
  кц
  нц для i от shift + la + 1 до lb
    y := код(b[i]) - код('0')
    утв 0 <= y < D
    z := y + carry
    carry := div(z, D)
    r := mod(z, D)
    b[i] := символ(r + код('0'))
  кц при carry = 0
  если carry > 0 то
    b := b + символ(carry + код('0'))
  все
кон

алг лит mul1(цел x, лит b)
нач
  утв 0 <= x < D
  цел lb, carry = 0, i, y, z, r
  лит c = ""

  если x = 0 то
    знач := c
    выход
  все

  lb := длин(b)
  нц для i от 1 до lb
    y := код(b[i]) - код('0')
    утв 0 <= y < D
    z := x * y + carry
    carry := div(z, D)
    r := mod(z, D)
    c := c + символ(r + код('0'))
  кц
  если carry > 0 то
    c := c + символ(carry + код('0'))
  все
  знач := c
кон

алг лит mul(лит a, лит b)
нач
  цел la, lb, carry = 0, i, x, y, z, r
  лит res = "", c
  лит таб rss[1:D-1]

  la := длин(a)
  lb := длин(b)

  если la = 0 или lb = 0 то
    знач := res
    выход
  все

  нц для i от 1 до D - 1
    rss[i] := ""
  кц

  нц для i от 1 до lb
    y := код(b[i]) - код('0')
    утв 0 <= y < D
    если 0 < y то
      если длин(rss[y]) > 0 то
        c := rss[y]
      иначе
        c := mul1(y, a)
        rss[y] := c
      все
      addhere(c, i - 1, res)
    все
  кц
  знач := res
кон

Clone this wiki locally