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"
fiif [ $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))
finum1=${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
Неплохо бы к таким примерам, добавлять ещё и
цель, смысл, оправданность и рабочий пример.
+1
Пример библиотеки для операций с "длинными" числамиhttp://brain.tltsu.ru/~brain/projects/bla.shtml
там же на ней реализовано умножение матриц.
я же просил со смыслом...Толку от этого ... На bash_e я могу сервак написать.
мда два дня назад столкнулся с проблемой сравнения в BASH-e float значенийи прочёл, что BASH не знает что такое float для него 3.7 это строка
и конечно же две строки на больше или меньше сравнить нельзя кроме как в ASCII сравнении
пришлось рулить bc
спросите где ваще это применялось ? в обычном фильтре для Postfix-а когда надо было сравнивать результат оценки Spamassassin-a с установленным средним и максимальным значениями _SCORE_
Умножение матриц это для вас не "смысл"??? :) :) :)
>Умножение матриц это для вас не "смысл"??? :) :) :)Смысл, но не на bash и не float :)
Кстати, частое порождение sed'ов и echo-ев сильно замедляет работу кода... Мне кажется лучше изпользовать возможности BASH для обработки чисел.
Тем более, что небольшие числа BASH вообще умеет воспринимать числами и производить над ними арифметические операции.
> Кстати, частое порождение sed'ов и echo-ев сильно замедляет работу кода... Мне кажется лучше изпользовать возможности BASH для обработки чисел.С другой стороны, лучше оставаться в рамках POSIX Shell по возможности...
К вопросу о смысле: реализация в рамках POSIX Shell работает настолько медленно что в моём случае (длинные числа) трудно даже отладку вести: тесты работают чересчур медленно.
Посему, POSIX - хорошо, и Ъ, но уж точно не нужно. А вот реализация с "фичами" BASH
работает на удивление быстро, даже умножение матриц. Это может придать смысл самой идее...
sizeof int в bash - 64 бита между прочим, да еще и бит знака хранится отдельно!
Я придумал СМЫСЛ!Хороший довесок к резюме, на тему знания BASH, при поступлении на работу. =)
>Хороший довесок к резюме, на тему знания BASH, при поступлении на работу.
> =)Уверен, что "написал преобразование Фурье и библиотеку операций над матрицами на bash-е" будет адекватно воспринято при собеседовании? %-))
>>Хороший довесок к резюме, на тему знания BASH, при поступлении на работу.
>> =)
>
>Уверен, что "написал преобразование Фурье и библиотеку операций над матрицами на bash-е"
>будет адекватно воспринято при собеседовании? %-))Вполне, как человек добивающийся цели, ни смотря на идиотство (задание начальства) и трудоемкость. (хотя посчитать sin()/сos() через ряд Маклорена не так уж и гиморно). :)
математическая разность float-чисел в обход bc, вариант 2:
echo "4,45 55,3" | awk '{print $1-$2}'
Ага...Гиперболический синус от математической разности натурального логорифма и корня и двух, в обход bc -l
echo "evalf(sinh(ln(3.14159265)-sqrt(2.0)),25);" | /opt/maple11/bin/maple -q
-0.2727572577106891599885980=)
Вообще-то есть octave
Да и перл уже установлен на 90% *никсов.
0o на кой ляд вам на баше понадобились числа с плавающей точкой вобще? =\
>0o на кой ляд вам на баше понадобились числа с плавающей точкой
>вобще? =\Автор ешё не ответил.
Сами мучаемся!
%) Пока предположения следующие: для воспитания характера (и спать на ржавых гвоздях обязательно); для начальства; для резюме (покладист, исполнителен: сказали на баше - написал на баше // фантазия с годами проходит, а "профессионализм" остаётся?!); фантастическое - "порождение echo-в и sed-ов" наверное(!) медненнее, чем такая-^^ "математика" на самом баше (кстати, echo в баше - builtin, см. `type echo`); ....
re,
Ну нафлудили. Смысл в что сто смысла нет, просто делать было нечего и довольно сильно бесило то что в интернете нет ни одного примера подобной операции без вызова bc, хоть это и возможно :)
btw, использование функции реально быстрее вызова bc. Попробуйте в млн итераций в цикле, кроме этого bc в цикле офигевает от слишком частого запуска через "|" и отказывается работать :).Умножение тож делал от нечего делать, но за ссылку спасибо.
Сервак(web-сервер) на баше люди тоже уже писали много раз, от части это тоже вдохновило.