Вычислить квадратный корень из десятичных знаков в bash - PullRequest
2 голосов
/ 22 октября 2019

Я пишу простой bash-скрипт для вычисления квадратного корня до 3 десятичных знаков по умолчанию, но пользователь может установить количество мест ... Ничего сложного, я просто перебираю от 1 до самого нижнего квадратного корня. Так как мой bash все еще базовый, это то, что я придумал.

#!/usr/bin/env bash

num=${1}
places=${2-3}
i=0

while [[ $(( i*i )) -lt ${num} ]]    // <= The problem should be here
do
    i=$(( i + 1 ))
done

echo ${i};
rem=$(( num % i ))
root="${i}."
for (( j=0; j<places; j++ ))
do
    rem=$((rem * 10))
    root="$root$((rem / i))"
    rem=$((rem % i))
done
echo ${root}

Но по какой-то причине он не даст правильного результата для широкого диапазона чисел, таких как bashfile.sh 9 // will produce 3.000 but bashfile.sh 8 will return 3.666 любезно помогите, что не так с while [[ ]]

1 Ответ

1 голос
/ 22 октября 2019

Вот довольно простое, хотя и не очень эффективное решение:

#!/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)}"
...