переполнение в скрипте bash для вычисления коэффициентов многочлена - PullRequest
0 голосов
/ 23 апреля 2019

Я использую bash для вычисления многочленных коэффициентов. Код следует ниже:

#!/bin/bash

function factorial {
  declare n=$1
    (( n < 2 )) && echo 1 && return
      echo $(( n * $(factorial $((n-1))) ))
}

function binomial {
  declare n=$1
  declare k=$2
  echo $(( $(factorial $((n))) / ( $(factorial $((k))) * $(factorial $((n-k)))  ) ))
}

function multinomial {
  arr=("$@")
  declare mcoeff=1
  declare n=0
  for k in "${arr[@]}";
  do
    ((n=$n+$k))
    ((mcoeff=$mcoeff*$(binomial "$n" "$k")))
  done
  echo "$mcoeff"
}

multinomial $@

Кажется, в некоторых ситуациях у меня переполнение.

$ ./multinomial.sh 4 5 6
630630
$ ./multinomial.sh 4 5 6 7
-119189070

Есть идеи, как это исправить?

1 Ответ

3 голосов
/ 23 апреля 2019

Оболочка - это среда, из которой можно вызывать инструменты с языком для последовательности этих вызовов. Он не предназначен для полнофункционального языка программирования и не предназначен для сложных вычислений. Попробуйте вместо этого, я только что перевел ваш код оболочки в эквивалентный awk:

$ cat multinomial.sh
#!/usr/bin/env bash

awk -v nums="$*" '
function factorial(n) {
    if ( n < 2 ) {
        return 1
    }
    return n * factorial(n-1)
}

function binomial(n,k) {
    return factorial(n) / ( factorial(k) * factorial(n-k) )
}

function multinomial(str,   arr, mcoeff, n, k) {
    split(str,arr)
    mcoeff = 1
    n = 0
    for (j=1; j in arr; j++) {
        k = arr[j]
        n = n + k
        mcoeff = mcoeff * binomial(n,k)
    }
    return mcoeff
}

BEGIN { print multinomial(nums) }
'

.

$ ./multinomial.sh 4 5 6
630630

$ ./multinomial.sh 4 5 6 7
107550162720

$ ./multinomial.sh 4 5 6 7 8
629483036137955968
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...