function math_minus {
num1_point=$(echo $1|sed 's/.*\..*/true/');
num2_point=$(echo $2|sed 's/.*\..*/true/');
if [ $num1_point = "true" ]; then
num1_1=$(echo $1|sed 's/\..*$//');
num1_2=$(echo $1|sed 's/^.*\.//');
else
num1_1=$1;num1_2=0;
fi; if [ $num2_point == "true" ]; then
num2_1=$(echo $2|sed 's/\..*$//');
num2_2=$(echo $2|sed 's/^.*\.//');
else
num2_1=$2;num2_2=0;
fi
num1_2_len=${#num1_2}
num2_2_len=${#num2_2}
if [ $num1_2_len -lt $num2_2_len ]; then
len_diff=$((num2_2_len-num1_2_len))
for i in `seq 1 $len_diff`; do
diff_nulls="${diff_nulls}0"
done
num1_2="${num1_2}$diff_nulls"
fi; if [ $num1_2_len -gt $num2_2_len ]; then
len_diff=$((num1_2_len-num2_2_len))
for i in `seq 1 $len_diff`; do
diff_nulls="${diff_nulls}0"
done
num2_2="${num2_2}$diff_nulls"
fi if [ $num1_1 -gt $num2_1 ]; then
num1=$((num1_1-num2_1));
fi
if [ $num2_1 -gt $num1_1 ]; then
num1=$((num2_1-num1_1));
fi
num1_len=${#num1}
num2_len=$((num1_len+1))
num1="${num1}${num1_2}"
num2="${num2}${num2_2}"
if [ $num1 -gt $num2 ]; then
result=$((num1-num2))
else
result=$((num2-num1))
fi
num1=${result:0:num1_len}
num2=${result:num2_len}
result="${num1}.${num2}"
if [ "$result" == "." ]; then
result=0
fi
echo "$result"
}
Выше превиденный пример является концептуальной демонстрацией,
в скриптах для выполнения сложных матеметических операций более подходит bc:
echo "scale=5; a=4.1; (a+80)*3 - a^2 + l(a)" | bc -l
где через scale задается точность в знаках после запятой,
l() - натуральный логарифм, "^" - возведение в степень.
Возможности языка bc очень широки, поддерживаются циклы, условия, функции
Другая форма использования:
var1=2; var2=$(echo "scale=5; $var2 / 2" | bc)
Для преобразования формата представления чисел удобно использовать утилиту dc
Перевод числа 11 в шестнадцатеричную форму:
echo "11 16 o p" | dc
в двоичную
echo "11 2 o p" | dc
Выполнения простых целочисленных операций:
echo $(( 20 / 2 ))
var1=2; var2=$(( $var1 + 1 ))
URL:
Обсуждается: https://www.opennet.ru/tips/info/1661.shtml