Занимательная математика командной строки

в 21:41, , рубрики: awk, linux, shell, математика

Если вы пользователь Linux, Free/Open BSD или другой свободной ОС, есть вероятность, что интерфейс командной строки вам не чужд. В таком случае можно использовать командную оболочку для простых арифметических действий. Для этого не нужно устанавливать дополнительных программ, все уже есть в базовом наборе операционной системы. Они позволяют качественно заменить привычный калькулятор на столике счетовода.

Занимательная математика командной строки - 1

bash калькулятор целочисленный

Арифметические операции с целочисленными в bash будут выглядеть так:

$((expression))
$(( n1+n2 ))
$(( n1/n2 ))
$(( n1*n2 ))
$(( n1-n2 ))

Например:

$ echo $((15+25))
$ 40

На man странице bash, в разделе ARITHMETIC EVALUATION вы можете ознакомиться с приоритетом исполнения действий операторов

И, кстати, можно получить тот же результат, используя команду expr целочисленное выражение, вместо подстановки с двойными скобками в командах вывода.

$ expr 15 + 25
$ 40

bc мэдскиллз

Целочисленные выражения это конечно хорошо, но как-то маловато даже для калькулятора. Благо в наборе есть еще bc — Си-подобный интерактивный интерпретатор. Не будем тратить время на сложение и вычитание, перейдем сразу к более интересным занятиям.

$ echo 7^7 |bc
823543

Это уже получше калькулятора, так как позволяет получить любое количество чисел в дробной части с помощью переменной scale. Остерегайтесь поддельных проприетарных версий bc, так как они поддерживают всего-лишь 99 знаков после запятой!

$ echo 'scale=30;sqrt(2)' | bc
1.414213562373095048801688724209

Еще 2 важные переменные: ibase и obase указывают на основание входящих и исходящих чисел.

$ echo 'ibase=16;obase=A;FF' | bc
255

Тут, кстати, есть засада. Посмотрите на эти два примера. Вроде бы пытаешься сделать то же самое, но результат разный. Вся суть в том, что в первом примере ibase=2, но сама obase=10 принимает значение 2 в силу того, что ibase определяет по базе obase и 10 становится равной 2. Чтобы разорвать этот круг, надо использовать hex.

$ echo 'ibase=2;obase=10;10' | bc
10
$ echo 'ibase=2;obase=A;10' | bc
2

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

$ echo '4^4^4' |bc
13407807929942597099574024998205846127479365820592393377723561443721
76403007354697680187429816690342769003185818648605085375388281194656
9946433649006084096
$ echo '(4^4)^4' |bc
4294967296

Помимо этих художеств, bc имеет еще интерактивный режим в котором пищит и все портит делает все то же самое, но уже напрямую, без конвейера. Ключ -q нужен, чтобы подавить гнушное приветствие.

$ bc -q
4^4^4
13407807929942597099574024998205846127479365820592393377723561443721
76403007354697680187429816690342769003185818648605085375388281194656
9946433649006084096
quit

Замер производительности процессора с bc

Много лун назад на одном популярном англоязычном форуме, ныне покойном, предложили гениально простой способ нагреть проц и посчитать его скорость в попугаях.

time echo "scale=5000; 4*a(1)" | bc -l -q

Мы подгружаем в bc математическую библиотеку опцией -l и просим выдать число π с точностью 5000 знаков после запятой. Мой результат вычисления на Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz:

real    0m24.507s
user    0m24.490s
sys     0m0.000s

Подгружаемые математические функции

s (x) The sine of x, x is in radians.
c (x) The cosine of x, x is in radians.
a (x) The arctangent of x, arctangent returns radians.
l (x) The natural logarithm of x.
e (x) The exponential function of raising e to the value x.
j (n,x) The Bessel function of integer order n of x.

Скрипты bc

В bc можно, если очень нужно, определять функции и запускать скрипты. Определение функции имеет следующий синтаксис:

define name ( parameters ) { newline
    auto_list statement_list }

Определены условные операторы if и else, причем последний не обязательно использовать, а также заголовки цикла for и while. На Википедии можно просмотреть список математических операторов и сравнить с таковым в Си. А вот так выглядит расчет чисел Фибоначчи в bc.

#!/usr/bin/bc -q
define fibo(n) {
    if (x <= 2) return n;
    a = 0;
    b = 1;
    for (i = 1; i < n; i++) {
        c = a+b; a = b; b = c;
    }
    return c;
}
fibo(1000)
quit

Как ЯП bc не взлетел, однако в качестве настольного калькулятора он более чем хорош.

awk: арифмометр и гадалка

Мне не часто доводилось пользоваться awk, поэтому каждый раз я с удивлением обнаруживаю новые возможности этой программы. Если нужно посчитать логарифмы или синусы, не спешите паниковать, man awk вам поможет. Вот так мы получили квадратный корень.

awk 'BEGIN{print sqrt(196)}'
14

А вот мы уже логарифмируем число π, 5000 знаков которого мы уже вычисляли с помощью bc.

awk 'BEGIN{print log(3.141592653589793238462643383279502884197169399375105820974944592307)}'
1.14473

Оглашаю полный список возможностей

atan2(y, x)   Return the arctangent of y/x in radians.
cos(expr)     Return the cosine of expr, which is in radians.
exp(expr)     The exponential function.
int(expr)     Truncate to integer.
log(expr)     The natural logarithm function.
rand()        Return a random number N, between 0 and 1, such that 0 ≤ N < 1.
sin(expr)     Return the sine of expr, which is in radians.
sqrt(expr)    Return the square root of expr.
srand([expr]) Use expr as the new seed for the random number generator.  If no expr is provided, use the time of day. Return the previous seed for the random number generator.

Иногда, хочется довериться судьбе и послать все на три буквы — awk. Вообще-то, это пример из книги издательства O'Reilly, имитирует бросание монетки, выдавая 2 разных события пить или не пить с одинаковой вероятностью.

#!/bin/bash
ans=`awk -vmin=0 -vmax=1 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'`

if [ $ans -eq 0 ]; then
    echo "no"
else
    echo "yes"
fi

В заключение

В нашей математической мастерской.еще очень много разных программ и если тема взлетит, попробуем перейти в первую и высшую лигу математического ПО с открытыми исходниками.

I. Замена калькулятора

  1. Встроенные средства командной оболочки: арифметические подстановки bash.
  2. Программа GNU bc.
  3. Неформат — awk.

II. Таблицы

  1. OpenOffice / LibreOffice Calc.
  2. KDE KSpread.
  3. GNOME Gnumeric.
  4. Одиночные, например: GNU Oleo и другие.

III. Специализированные математические программы, уровень студент+

  1. GNU Ocatve.
  2. Scilab.
  3. Maxima.
  4. R.
  5. Sage.

IV. Языки программирования, математические библиотеки и среды

  1. Ansi C, библиотеки math.h, complex.h, GSL и другие товарищи.
  2. Java Scientific Library
  3. Python, библиотеки SciPy, NumPy, Sympy и другие товарищи.
  4. COBOL.
  5. Fortran.
  6. Intel Math Kernel Library (Intel MKL)
  7. AMD Accelerated Parallel Processing Math (APPLM)
  8. AMD Core Math Library (ACML)

Список, естественно не полный, поэтому заранее прошу прощение, если не указал чей-то излюбленный математический пакет или ЯП. Последняя группа — поистине разливанное море разнообразного и годного софта.

А вот и обещанный мэдскиллз вместе с ответом на вопрос из картинки. Источник.

diff -u <(seq -f '%03.0f' 0 999) <((bc <<<'scale = 3009; 1 / 998001' | tr -d '\n'; echo) | sed s/.// | fold -3)

Автор: temujin

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js