Я все еще ищу чистый bcответ о том, как округлить только одно значение в функции, но вот чистый bashответ:
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
embiggen() {
local int precision fraction=""
if [ "$1" != "${1#*.}" ]; then # there is a decimal point
fraction="${1#*.}" # just the digits after the dot
fi
int="${1%.*}" # the float as a truncated integer
precision="${#fraction}" # the number of fractional digits
echo $(( 10**10 * $int$fraction / 10**$precision ))
}
# round down if negative
if [ "$float" != "${float#-}" ]
then round="-5000000000"
else round="5000000000"
fi
# calculate rounded answer (sans decimal point)
answer=$(( ( `embiggen $float` * 100 + $round ) / `embiggen 1.18` ))
int=${answer%??} # the answer as a truncated integer
echo $int.${answer#$int} # reassemble with correct precision
read -p "Press any key to continue..."
По сути, это тщательно извлекает десятичные дроби, умножает все на 100 миллиардов (10¹⁰, 10**10in bash), корректирует точность и округление, выполняет фактическое деление, делит обратно до соответствующей величины, а затем повторно вводит десятичное число.
Шаг за шагом:
В embiggen()функции присваивает усечено целым формы его аргумента $intи сохраняет число после точки в $fraction. Количество дробных цифр указано в $precision. В математике умножает 10¹⁰ по конкатенации $intи , $fractionа затем корректирует , что соответствует точности (например , embiggen 48.86становится 10¹⁰ × 4886/100 и возврат 488600000000которых является 488600000000).
Нам нужна конечная точность в сотых долях, поэтому мы умножаем первое число на 100, добавляем 5 для округления и затем делим второе число. Это назначение $answerоставляет нам в сто раз окончательный ответ.
Теперь нам нужно добавить десятичную точку. Мы присваиваем новое $intзначение $answerисключению двух последних цифр, затем echoоно ставится точкой и $answerисключает $intзначение, о котором уже позаботились. (Не берите в голову ошибку подсветки синтаксиса, которая заставляет это походить на комментарий)
(Bashism: возведение в степень не является POSIX, так что это bashism. Чистое решение POSIX потребовало бы циклов для добавления нулей, а не использования степеней десяти. Кроме того, «embiggen» - совершенно непонятное слово.)
Одна из основных причин, по которой я использую zshсвою оболочку, заключается в том, что она поддерживает математику с плавающей запятой. Решение этого вопроса довольно простое в zsh:
printf %.2f $((float/1.18))
(Я бы хотел, чтобы кто-нибудь добавил комментарий к этому ответу с хитростью, чтобы включить арифметику с плавающей запятой bash, но я почти уверен, что такой функции еще не существует.)