Obwohl Sie bitten, dies in Bash zu tun, gibt es keine native Unterstützung für Funktionen wie Quadratwurzel oder Decke. Es wäre einfacher, zu Perl zu delegieren:
perl -wmPOSIX -e "print POSIX::ceil((sqrt(1 + 8 * $n) - 1)/2)"
Alternativ können Sie bc
verwenden, um die Quadratwurzel zu berechnen, und einige Bash die Decke zu berechnen.
Lassen Sie uns eine Funktion definieren, die das Ergebnis der Formel druckt mit sqrt
von bc
:
formula() {
local n=$1
bc -l <<< "(sqrt(1 + 8 * $n) - 1)/2"
}
Die -l
Flagge ändert die scale
von der Standard 0 bis 20. Dies wirkt sich auf die Skala in der Anzeige des Schwebens Punkt Ergebnisse. Zum Beispiel mit der Standard-Null würde 10/3
nur drucken 3. Wir müssen die Floating-Point-Details im nächsten Schritt die Decke zu berechnen.
ceil() {
local n=$1
local intpart=${n%%.*}
if [[ $n =~ \.00*$ ]]; then
echo $intpart
else
echo $((intpart + 1))
fi
}
Die Idee dabei ist, den ganzzahligen Teil zu extrahieren, und wenn der Dezimalteil alle Nullen, dann drucken wir einfach den ganzzahligen Teil, sonst der ganzzahlige Teil + 1, so dass die Obergrenze ist.
Und eine letzte einfache Funktion, die die oben genannten Funktionen kombiniert das Ergebnis zu erhalten, die Sie wollen:
compute() {
local n=$1
ceil $(formula $n)
}
Und einen Kontrolleur Funktion testen:
check() {
local n num
for n; do
num=$(formula $n)
echo $n $num $(compute $n)
done
}
Lassen Sie uns es versuchen:
check 1 2 3 4 7 11 12 16 17
Es produziert:
1 1.00000000000000000000 1
2 1.56155281280883027491 2
3 2.00000000000000000000 2
4 2.37228132326901432992 3
7 3.27491721763537484861 4
11 4.21699056602830190566 5
12 4.42442890089805236087 5
16 5.17890834580027361089 6
17 5.35234995535981255455 6
Es gibt sicherlich kein 'sqrt' Operator in' bash'. –
Muss ich meine eigene sqrt-Funktion schreiben? – user8926565
Nicht sicher ob es hilft, aber da '(8n + 1)' ungerade ist, dann wenn 'sqrt (8n + 1) 'ein ganzzahliger Wert ist, muss es auch ungerade sein. Folglich ist das Subtrahieren von (1) und das Dividieren durch (2) immer ganzzahlig. Wenn also "(n)" für jede ganze Zahl "(k)" als "k (k + 1)/2" ausgedrückt werden kann, dann ist das Ergebnis eine ganze Zahl. Andernfalls füge eins zum ganzzahligen Teil hinzu. –