Вот довольно простое, хотя и не очень эффективное решение:
#!/bin/bash
num=$1
prec=${2:-3}
for (( i=0; i < prec; ++i )); do let num*=100; done
for (( sqrt=0; sqrt*sqrt <= num; ++sqrt )); do :; done
let --sqrt
sqrt="${sqrt:0:-prec}.${sqrt: -prec}"
echo $sqrt
Чтобы ответить на ваш вопрос («что не так с while [[ ]]
»), ваше сравнение было немного неверным. Вместо -lt
(то есть <
) это должно было быть <=
. И вам нужно было вычесть 1 из i
после цикла, чтобы получить правильную целую часть квадратного корня.
Я не мог понять смысл второй части вашего кода, которая вычисляет десятичные разряды. Однако простое решение состоит в том, чтобы вместо этого предварительно умножить исходное число, чтобы получить необходимую точность, что я и сделал выше.
ОБНОВЛЕНИЕ
Как указал @ dash-o, если вы используете bash, скорее всего, у вас установлен либо bc, либо awk, которые лучше подходят для этого:
num=$1
prec=${2:-3}
# using bc
echo "scale=$prec; sqrt($num)" | bc
# using awk
awk "BEGIN {printf \"%.${prec}f\n\", sqrt($num)}"