The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

Пример функции математической разности float-чисел в обход bc
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 ))
 
02.06.2008 , Автор: Alexander Driantsov
Ключи: bash, shell, math, bc / Лицензия: CC-BY
Раздел:    Корень / Программисту и web-разработчику / Shell / Готовые скрипты

Обсуждение [ Линейный режим | Показать все | RSS ]
  • 1.1, pavlinux (ok), 17:20, 02/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Неплохо бы к таким примерам, добавлять ещё и
    цель, смысл, оправданность и рабочий пример.
     
  • 1.2, Fen1x (?), 18:38, 02/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    +1
     
  • 1.3, brain (??), 18:43, 02/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Пример библиотеки для операций с "длинными" числами

    http://brain.tltsu.ru/~brain/projects/bla.shtml

    там же на ней реализовано умножение матриц.

     
     
  • 2.7, pavlinux (ok), 18:58, 02/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    я же просил со смыслом...

    Толку от этого ...  На bash_e я могу сервак написать.

     
     
  • 3.16, Paranoidchaos (?), 13:01, 07/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    мда два дня назад столкнулся с проблемой сравнения в BASH-e float значений

    и прочёл, что BASH не знает что такое float  для него 3.7  это строка

    и конечно же две строки на больше или меньше сравнить нельзя кроме как в ASCII сравнении

    пришлось рулить bc

    спросите где ваще это применялось ? в обычном фильтре для Postfix-а когда надо было сравнивать результат оценки Spamassassin-a с установленным средним и максимальным значениями _SCORE_

     
  • 3.19, Щекн Итрч (?), 05:47, 13/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    Умножение матриц это для вас не "смысл"??? :) :) :)
     
     
  • 4.20, pavlinux (ok), 06:45, 13/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    >Умножение матриц это для вас не "смысл"??? :) :) :)

    Смысл, но не на bash и не float :)



     

  • 1.4, brain (??), 18:46, 02/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Кстати, частое порождение sed'ов и echo-ев сильно замедляет работу кода... Мне кажется лучше изпользовать возможности BASH для обработки чисел.
    Тем более, что небольшие числа BASH вообще умеет воспринимать числами и производить над ними арифметические операции.
     
     
  • 2.5, const (??), 18:49, 02/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    > Кстати, частое порождение sed'ов и echo-ев сильно замедляет работу кода... Мне кажется лучше изпользовать возможности BASH для обработки чисел.

    С другой стороны, лучше оставаться в рамках POSIX Shell по возможности...

     
     
  • 3.6, brain (??), 18:54, 02/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    К вопросу о смысле: реализация в рамках POSIX Shell работает настолько медленно что в моём случае (длинные числа) трудно даже отладку вести: тесты работают чересчур медленно.
    Посему, POSIX - хорошо, и Ъ, но уж точно не нужно. А вот реализация с "фичами" BASH
    работает на удивление быстро, даже умножение матриц. Это может придать смысл самой идее...
     
  • 2.12, alext (??), 23:35, 02/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    sizeof int в bash - 64 бита между прочим, да еще и бит знака хранится отдельно!
     

  • 1.8, pavlinux (ok), 19:04, 02/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    Я придумал СМЫСЛ!

    Хороший довесок к резюме, на тему знания BASH, при поступлении на работу.  =)

     
     
  • 2.9, Andrey Mitrofanov (?), 20:49, 02/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    >Хороший довесок к резюме, на тему знания BASH, при поступлении на работу.
    > =)

    Уверен, что "написал преобразование Фурье и библиотеку операций над матрицами на bash-е" будет адекватно воспринято при собеседовании? %-))

     
     
  • 3.10, pavlinux (ok), 21:08, 02/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    >>Хороший довесок к резюме, на тему знания BASH, при поступлении на работу.
    >> =)
    >
    >Уверен, что "написал преобразование Фурье и библиотеку операций над матрицами на bash-е"
    >будет адекватно воспринято при собеседовании? %-))

    Вполне, как человек добивающийся цели, ни смотря на идиотство (задание начальства) и трудоемкость. (хотя посчитать sin()/сos() через ряд Маклорена  не так уж и гиморно).   :)


     

  • 1.11, littlesavage (?), 22:40, 02/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    математическая разность float-чисел в обход bc, вариант 2:
    echo "4,45 55,3" | awk '{print $1-$2}'
     
     
  • 2.13, pavlinux (ok), 03:08, 03/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    Ага...

    Гиперболический синус от математической разности натурального логорифма и корня и двух, в обход bc -l

    echo "evalf(sinh(ln(3.14159265)-sqrt(2.0)),25);" |  /opt/maple11/bin/maple -q
                  
    -0.2727572577106891599885980

    =)

     
     
  • 3.17, yurror (?), 05:42, 10/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    Вообще-то есть octave
     
  • 3.18, terr0rist (ok), 12:55, 11/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    Да и перл уже установлен на 90% *никсов.
     

  • 1.14, naquad (??), 01:06, 05/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    0o на кой ляд вам на баше понадобились числа с плавающей точкой вобще? =\
     
     
  • 2.15, Andrey Mitrofanov (?), 11:32, 05/06/2008 [^] [^^] [^^^] [ответить]  
  • +/
    >0o на кой ляд вам на баше понадобились числа с плавающей точкой
    >вобще? =\

    Автор ешё не ответил.

    Сами мучаемся!

    %) Пока предположения следующие: для воспитания характера (и спать на ржавых гвоздях обязательно); для начальства; для резюме (покладист, исполнителен: сказали на баше - написал на баше // фантазия с годами проходит, а "профессионализм" остаётся?!); фантастическое - "порождение echo-в и sed-ов" наверное(!) медненнее, чем такая-^^ "математика" на самом баше (кстати, echo в баше - builtin, см. 'type echo'); ....

     

  • 1.21, Lucf3r (??), 10:55, 16/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    re,
    Ну нафлудили. Смысл в что сто смысла нет, просто делать было нечего и довольно сильно бесило то что в интернете нет ни одного примера подобной операции без вызова bc, хоть это и возможно :)
     
  • 1.22, Lucf3r (??), 12:27, 16/06/2008 [ответить] [﹢﹢﹢] [ · · · ]  
  • +/
    btw, использование функции реально быстрее вызова bc. Попробуйте в млн итераций в цикле, кроме этого bc в цикле офигевает от слишком частого запуска через "|" и отказывается работать :).

    Умножение тож делал от нечего делать, но за ссылку спасибо.

    Сервак(web-сервер) на баше люди тоже уже писали много раз, от части это тоже вдохновило.

     

     Добавить комментарий
    Имя:
    E-Mail:
    Заголовок:
    Текст:




    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру