Вычисления в Линуксе

Что мы делаем, когда нам нужно что-то посчитать? Например посчитать совокупную стоимость продуктов, или выделяемую на резисторе мощность.

Мы достаем калькулятор (девайс) и тупо нажимаем соответствующие кнопки. В последнее время, если присмотреться, то калькуляторов даже меньше, чем компов. К тому же калькуляторы преимущественно — бухгалтерские. Инженерных калькуляторов, с синусами-косинусами найти сейчас стало очень сложно. Поэтому народ ненавязчиво запускает на телефоне или на компе программу программу-калькулятор и тыкает мышкой по кнопкам.

Вроде даже удобно. Да что там говорить — я и сам так делал до недавнего времени, когда считал итоговые суммы в расходных ордерах или производил не очень сложные математические расчеты.

Но совсем недавно я повторно для себя открыл программу-калькулятор. В первый раз, когда я с ним столкнулся, я еще мало что понимал про «дух Линукса», и, видимо, по этой причине я так и не смог оценить мощь калькулятора. Ну и ладно! Рукописи не горят, а реально красивые жемчужины, не замеченные сразу, ни куда не исчезают. Чуть позже они всегда возникают в поле зрения.

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

Забавно, что полное название программы включает в себя фразу «калькулятор с неограниченной точностью вычисления»

— Э-э… что сказал? Переведи!

Так вот, этот калькулятор может вычислять с точностью до 2 миллиардов (2 в степени 31) знаков после запятой. Конечно, такая точность нафиг никому не сдалась. Но приятно!

И это еще не всё! Основное у калькулятора есть ещё парочка таких же мощных преимуществ: его простата (в освоении и работе с ним) и то, что он является не просто калькулятором, а программируемым калькулятором. Иначе говоря, калькулятор может работать по программе, которую вы напишите.

Да, я совсем забыл сказать, что калькулятор называется незатейливо — bc.

Давайте поближе познакомиться с нашим инструментом.

Поскольку калькулятор консольный, то для работы с ним, нам понадобится консоль. Наберите в консоли:

$ bc

и вы попадете в среду калькулятора. Здесь ничего нет. Здесь мы набираем действия для вычисления типа:

2+3

Допустимы все арифметические знаки: ‘+’, ‘-‘, ‘*’ и ‘/’. Возведение в степень — знак ‘^’. Можете пока немного поиграться.

Чтобы выйти из калькулятора нужно набрать в нем команду quit. Но лучше сразу приучить себя к правильной работе в Линуксе: окончание работы с вводом — это тоже самое, что конец файла. Конец файла это символ, соответствующий комбинации клавиш Ctrl-D.

Нажмите Ctrl-D один раз. Если вы нажмете дважды, то вы закончите работать не только в калькуляторе (первое нажатие), но и в консоли (второе нажатие). Консоль ведь тоже ожидает ввода ваших команд, и когда ей говорят, что типа «всё, больше никакого ввода в этой жизни уже никогда не будет». И что ей остается делать? Она естественно закроется. По этому принципу действуют все консольные команды, которые воспринимают ввод с клавиатуры.

Ладно. Идем дальше.

Если вы успели заметить, то калькулятор оперирует с целыми числами. На самом деле он выводит на экран числа как целые, хотя вычисления происходят с действительными числами. Для того чтобы «повысить» точность вычислений, нам нужно задать количество знаков после запятой. Делается это командой scale. Например, следующая команда заставит калькулятор отображать все 20 цифр после запятой:

scale=20

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

Кроме переменной scale, в калькуляторе имеется еще три переменных, которые тоже определяют режим его работы.

Переменная last хранит результат последнего вычисления. Она также может принимать участие в дальнейших расчетах.

Переменные ibase и obase — оказались весьма к стати. Они определяют систему исчисления для входных чисел (которые мы вводим) и для чисел, которые выводятся калькулятором в качестве результата вычислений.

Базы счислений могут быть любыми — от 2 до 36. Но обычно люди пользуются двоичными (2), десятичными (10) и шестнадцатеричными (16) числами. Раньше в программировании компьютеров широко использовались восьмеричные (8) числа, теперь они практически не используются.

Зато недавно образовалась новая база — «четыричных» (или как их правильно назвать?) чисел. Сфера ее приложения — белковое программирование, вычислительная биология. Числам соответствуют четыре типа аминокислот (азотистых оснований): аденин, гуанин, тимин и цитозин. Из них строится ДНК. Но это уже совсем другая тема.

Итак, если вам нужно перевести число из одной системы исчисления в другую, просто укажите базис ввода и базис вывода. Допустим, мы хотим знать, как будет выглядеть десятичное число 1000 в 16-ричной кодировке:

ibase=10
obase=16
1000

после нажатия на Enter получаем 3E8. Можете попробовать перевести числа в двоичную систему. В общем, поиграйтесь!

Кроме этих переменных вы можете определить свои. Правило тут такое, что все переменные — числовые. В калькуляторе нет логических переменных и нет переменных для строк или символов.

Кроме того, запомните, что имена переменных должны быть содержать только строчные буквы (маленькие), поскольку прописные буквы (большие) калькулятор интерпретирует как цифры. Имена переменных могут содержать цифры (0-9) и знак подчеркивания ‘_’. Но начинаться они должны только с буквы.

Такие правила игры с буквами объясняются тем, что в системах счисления, больших 10, в качестве цифр используются буквы латинского алфавита. Например, шестнадцатеричные цифры — это десять цифр от 0 до 9 и еще шесть цифр, которые выражаются буквами латинского алфавита, — A, B, C, D, E  и F. Ну а поскольку калькулятор поддерживает систему счисления до 36-ой степени, то под цифры отводятся все буквы латинского алфавита.

В общем, по регистру букв калькулятор определяет что перед ним — число или переменная.

Калькулятор понимает многосложные вычисления и действия со скобками. Например, вы можете задать ему такое вычисление:

2 + 3 * (4 - 5)

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

alpha = 3
beta = 4
gamma = 5
2 + alpha * (beta - gamma)

Конечно, с целыми числами работать не очень интересно. Поэтому давайте увеличим точность вычислений до 10 знаков, если вы это еще не сделали.

scale=10

Если вы успели заметить, что действия в калькуляторе можно выражать не в одной строке, а разносить их на несколько строк, то вы на правильном пути. Разнесенные действия на несколько строк — это зачатки программирования.

Это — Линукс! Мы ведь вместо клавиатурного ввода можем сделать ввод из файла. Давайте создадим простой текстовый файл с именем test-1.bc и запишем в него следующий текст:

scale = 10
alpha = 3
beta = 4
gamma = 5
2 + alpha * (beta - gamma) / 6
quit

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

Теперь давайте запустим на исполнение нашу первую программу:

$ bc -q test-1.bc
1.5000000000

Запуск калькулятора я осуществил с ключом -q. Этот ключ отключает вывод начального «приветствия» при запуске калькулятора. Попробуйте запустить калькулятор без этого ключа и вы сразу поймете зачем он нужен.

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

Этот калькулятор допускает два вида комментариев. Первый вид — это стандартный Си-шный комментарий:

/* это Си-шный комментарий */

Второй тип комментариев пришел из скриптовых языков. Он начинается с символа ‘#‘ и заканчивается в конце строки:

# Второй тип комментария

Давайте подпишем нашу программу так, чтобы было ясно, что она делает:

/*
   Тестовая программа.
   Ничего полезного не делает, просто я изучаю инструмент.
*/

scale = 10

/* Зададим начальные значения переменным */
alpha = 3
beta = 4
gamma = 5

/* Подсчитаем сложнейшее математическое выражение */
2 + alpha * (beta - gamma) / 6

# Если комментарий однострочный, то удобнее применять второй тип

quit    # Ты кто такой? Давай до свидания!

Линейное программирование — это не интересно, да и пользы от такой программы-длинной_макаронины не особо много! Калькулятор поддерживает не только оператор выбора if, но и операторы цикла for и while. Если вы знакомы с языком Си, то вам будет легче понять эти операторы, а так же операторы прерывания цикла break и перехода на следующую итерацию continue, которые

Давайте напишем программу test-2.bc для вывода таблицы квадратов чисел от 1 до 10.

# Знакомимся с циклами

for (i = 1; i <= 10; i++)
  print i, " : ", i * i, "\n"

quit

Вот так мы нечаянно познакомились с оператором вывода print. Противоположный ему оператор — оператор ввода read. Давайте чуть-чуть переделаем нашу программу, сделаем ее интерактивной:

# Знакомимся с циклами

# Получить верхний предел таблицы
print "Введите максимум ... "
max = read()

for (i = 1; i <= 10; i++)
  print i, " : ", i * i, "\n"

quit

Поиграемся с ветвлениями. Давайте составим программу для решения квадратного уравнения.

Я на всякий случай напомню, что это уравнения типа ax² + bx + c = 0. Для нахождения корней используется дискриминант, который вычисляется по формуле D = b² — 4ac. Корни уравнения находятся по формуле x = (-b ± √D) / 2a.

В зависимости от знака дискриминанта количество корней уравнения может быть два (D > 0), может быть один корень (D = 0), а может и не быть корней вообще (D < 0). Мне сейчас возразят, что в пространстве комплексных чисел корней всегда два. Но я хотел бы решать задачу по-школьному — в пространстве действительных чисел.

Создаем файл с именем axx+bx+c=0.bc и записываем в него следующий текст:

# Решаем квадратное уравнение

scale = 6

# Получить коэфициенты
print "Введите а ... "
a = read()
print "Введите b ... "
b = read()
print "Введите c ... "
c = read()

print "\n"

# Посчитать дискриминант
d = b * b - 4 * a * c

# Определим, сколько корней в уравнении
if (d < 0) {
  print "Корней нет\n"
} else if (d == 0) {
  x = -b / (2 * a);
  print "Корень один\n"
  print "  x = ", x, "\n"
} else {
  print "Два корня:\n"
  d1 = sqrt(d)
  x1 = (-b - d1) / (2 * a)
  x2 = (-b + d1) / (2 * a)
  print "  x1 = ", x1, "\n"
  print "  x2 = ", x2, "\n"
}

quit

Этот калькулятор оказался несколько своеобразный. Ну что ж, нужно просто привыкнуть к его индивидуальным особенностям. Когда вы будете делать не большие расчеты, то с его причудами вы скорее всего и не столкнетесь. Но если вам предстоят расчеты типа квадратного уравнения и более сложные, то лучше их выполнять на Python.

Какие ж особенности встретились в этом калькуляторе? На одну «неожиданность» обратил внимание Волька (см. комментарии ниже).

Еще одна неожиданность выразилась в том, что операторы выбора нужно писать в одну строку. Шаблон такой

if (УСЛОВИЕ) ОПЕРАТОР_1 else ОПЕРАТОР_2

Все хорошо, если у вас ОПЕРАТОР_1 и ОПЕРАТОР_2 односложные (не составные). Но такое редко бывает. Обычно в качестве оператора выступает сразу несколько последовательных операторов.

В языке Си с этим проблем нет — группа операторов заключается в фигурные скобки и всё это рассматривается как один оператор. У калькулятора командной строки тоже есть понятие о составном операторе, и он (составной оператор) тоже упаковывается в фигурные скобки.

Отличие же заключается в том, что для языка Си все белые символы (пробел, табуляция, новая строка) — однозначны. Поэтому для улучшения восприятия мы можем всяко форматировать исходный текст программы, заменяя пробелы на новую строку. Калькулятор такой вольности не допускает.

Калькулятор требует, чтобы лексемы if и else находились в одной строке с операторами. Единственное, что мы можем сделать, это операторы заключить в фигурные скобки. Поскольку составной оператор не накладывает ограничений на количество строк, то мы можем писать простые операторы (внутри составного) каждый в отдельной строке. Но при этом мы должны строго соблюсти условие, что начало и конец составного оператора должны быть в одной строке с лексемами if и else. На разгадку этой шарады я потратил часа два, пока понял, почему оператор if работает так странно.

Следующая фича в калькуляторе выражается в том, что после ввода переменных a, b и c, мне пришлось написать команду вывода символа новой строки print «\n». Без нее вывод вычисленных корней уравнения осуществляется несколько в искаженном виде — строка вывода «разламывается» пополам, и выводится как две строки. Причем разлом идет не по пробелам, а по словам. Вот такая особенность. Почему так происходит, я не знаю.

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

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

Давайте попробуем что-нибудь изобразить. Пусть функция будет вычислять общее сопротивления цепи при параллельно включении сопротивлений. Формула для вычисления следующая:

Rобщ = 1 / (1/R1 + 1/R2)

или что то же самое

Rобщ = (R1 * R2) / (R1 + R2)

Создаем файл test-3.bc со следующим содержимым:

scale = 6

define resist_par (resist1, resist2)
{
  resist = (resist1 * resist2) / (resist1 + resist2)
  return resist
}

r1 = 10
r2 = 20

r = resist_par(r1, r2)
print "r = ", r, "\n"

quit

Вы видите, что определение функции начинается с лексемы define, затем следует имя функции, затем в круглых скобках перечисляются параметры функции, после всего идет тело функции, которое заключается в фигурные скобки. Если функция возвращает значение, то в конце её должен присутствовать оператор return.

Вызов функции также не вызывает особых вопросов. Все предельно просто и понятно. Честно говоря, я бы не хотел углубляться в этом направлении. Калькулятор командной строки может выполнять все эти действия. Но если у вас возникают задачи написания программ, я все же не рекомендовал бы вам не заострять своё внимание на этом калькуляторе, а сразу переходить к изучению Python. Относительно создания минимальных программок, разницы между Python и bc — практически никакой! Но у Python неограниченная перспектива и мощь, а bc — это всего лишь программируемый калькулятор командной строки.

Есть ещё один один интересный момент по функциям. У калькулятора имеется возможность использовать математические функции типа синуса, косинуса, логарифма и так далее. Но для получения этой возможности нужно подключить внешнюю математическую библиотеку. Делается это с помощью ключа -l при вызове калькулятора:

$ bc -l -q

Теперь вы можете вычислять кое-какие математические функции. Например синус, косинус, натуральный логарифм. Причем, имена у функций будут не стандартные: не sin(x) — а s(x), не cos(y) — а c(y). Кроме того, будут отсутствовать функции тангенса, десятичного логарифма и многих других.

Конечно, это достаточно неприятный момент. Но с другой стороны, у нас есть все возможности исправить это положение. Самый просто способ сделать это — воспользоваться уже готовым файлом extensions.bc, который можно скачать, например, отсюда:

http://x-bc.sourceforge.net/extensions_bc.html

У меня в моём домашнем директории есть поддиректорий bin/. В него я складываю все свои программы, которые я отрабатываю и которые еще толком не устаканились. Сюда же я помещаю файлы наподобие extension.bc . К стати, я настоятельно рекомендую заглянуть в этот файл — посмотреть, что он делает и какие возможности он вам предоставляет.

После того как вы скачали и разместили этот файл у себя на компе, вам нужно создать переменную окружения, которую калькулятор будет считывать при запуске. В этой переменной помимо указания этого файла можно задать и другие опции. Например указать флаг «молчаливого» запуска -q (см. выше).

Добавьте в свой конфигурационный файл .profile следующую строку:

export BC_ENV_ARGS="-q -l $HOME/extensions.bc"

При следующем входе в систему вы будете награждены множеством функций в калькуляторе командной строки, а так же такими числами как число Пи и основание натурального логарифма. Если вы нуждаетесь еще в чем-то, то никто вам не запрещает наращивать и совершенствовать файл extetnsions.bc — всё в вашей воле! Используйте возможно на благо себе и обществу!

И наконец, я хотел бы затронуть еще один могучий вопрос — философию Линукса. А также я бы хотел сказать пару слов о том, как калькулятор командной строки вписывается в идеологию Линукса и чем это хорошо.

Парадигма Линукса состоит в том, что всё есть файл. Кроме того, не просто файл, а текстовый файл. Иначе говоря, все данные — это текст.

Конечно, тут много и долго можно спорить, что это не всегда удобно и не всегда это хорошо. Особенно, когда речь идет о быстродействии. Но эта парадигма «всё есть (текстовые) файлы» работает прекрасно. И это надо использовать!

Понятно, что использовать надо с умом. Никто не стоит у вас за спиной с вилами, когда речь идет о быстродействии. Никто не заставляет вас обрабатывать/передавать звуковые или тем более видео- потоки в текстовом формате. Это — исключения, и для них существуют двоичные форматы. Но та текстовая информация, с которой постоянно работает человек, ее-то зачем превращать в цифру?

Мы все знаем, каким словами сопровождается конфигурационные мега-файлы Реестра в Виндовсе. Хотели как лучше, хотели спрятать кое-какую информацию — в результате получили та-акой головняк, что ни боже мой! А оно нам надо?

Это один из основополагающих пунктов философии Линукса, касаемый проблемы формата файлов. Там где мы не придавлены жесткими требованиями по скорости передачи «жирных» потоков информации, нам не следует прибегать к двоичным форматам. Иначе будет себе дороже. Проверено на практике и не раз!

Второй фундаментальный камень в основе философии Линукса определяет взаимодействие программ, даже тех, которые еще пока не существуют. Этот принцип гласит, что все программы должны обладать двумя интерфейсами — программы должны поддерживать стандартный поток ввода и стандартный поток вывода. (Есть еще один стандартный поток — поток ошибок. Но он сейчас нам пока не нужен. Не будем заострять на нем внимание!)

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

Я должен это подчеркнуть особо — в мире Unix/Linux приоритетом в разработке программ является не их широкая функциональность (множество всяких разных функций), а их простота. Программа должна выполнять одну функцию, но предельно качественно.

Ведь если вдуматься в проблему, то становится всё прозрачно — чем меньше у программы всяких функций, тем меньшее размер ее кода. А чем меньше размер кода, тем меньше ошибок она содержит. Это давно известно и доказано, что количество ошибок в программе растет экспоненциально размеру ее кода. Поэтому, чем программа меньше, тем легче их выловить и устранить. И, тем самым, программа автоматически становится надежнее, а значит — качественнее.

Поскольку, каждая «отполированная» до совершенства программа обладает вводом и выводом, то недостающую функциональность можно получить присоединив другую «отполированную» программу.

В среде Unix/Linux вы можете соединять программы друг с другом в любой последовательности и в любом количестве. Они набираюся в цепочку как бусы на ниточку. Выход одной программы является входом другой. Попробуйте-ка так такой фокус проделать с графическими Виндовыми программами!

Вот, классический пример. Допустим, вам дан некоторый текст в виде файла. Вам нужно составить словарь используемых в тексте слов. Давайте посмотрим как это можно сделать.

Для начала просто выведем содержимое текстового файла в стандартный поток вывода. Стандартный поток вывода по умолчанию направлен в консоль (на экран). Команда cat как раз это и делает:

$ cat myfile.txt

В тексте файла могут встречаться числа и знаки, они нам не нужны. Мы должны их отфильтровать. Давайте заменим их на символ новой строки. Я перехватываю поток, направленный в консоль с помощью канала (символ ‘|‘) и направляю его на вход программы tr.

$ cat myfile.txt | tr -c '[:alnum:]' '\n*'

Выход команды tr — это стандартный поток вывода, которой, как мы уже знаем, направлен в консоль. Таким образом, сейчас на экране у нас появился не текст из файла, а какая-то мешанина из слов (по одному в строке), разделенных промежутками из пустых строк.

Если ваш файл оказался достаточно длинным, и физически не помещается на экран консоли, то (опять же!) вы можете перенаправить поток вывода с консоли на вход программы-пейджера less. Назначение этой программы — выводить информацию из входного потока порциями ровно такими, каков размер экрана.

$ cat myfile.txt | tr -c '[:alnum:]' '\n*' | less

Теперь мы можем пролистывать экран вверх и вниз (по-строчно и по-странично) с помощью клавиш управления курсором.
По окончании просмотра нужно нажать клавишу q.

Поигрались? — Хорошо! Идем дальше.

Теперь нам надо упорядочить слова. Причем нужно не просто упорядочить их по алфавиту, а еще желательно попутно исключить их дублирование. Делается это одним махом командой sort:

$ cat myfile.txt | tr -c '[:alnum:]' '\n*' | sort -iu | less

Теперь, слова выстроились по алфавиту. Но в тексте все еще присутствуют слова, которые начинаются на цифры. Удалим их с помощью утилиты grep:

$ cat myfile.txt | tr -c '[:alnum:]' '\n*' | sort -iu | grep -v '^[0-9]*$' | less

Я отлично понимаю ваше негодование против непонятной ослиной грамоты: «Это что за высеры такие — ‘[:alnum:]’ ‘\n*’ и ‘^[0-9]*$’ ???» Это не высеры, это так называемые регулярные выражения. Очень часто используются на практике и чрезвычайно сильно облегчают жизнь системным администраторам и программистам.

Не стоит нервничать! Придя в школу, вы ведь тоже не понимали таких чудесных вещей как функция синуса, логарифм, производная, интеграл… Но прошло время, и вы свободно ими оперируете в своей жизни. Ведь так? А иначе, что вы делаете тут у мена в блоге?

Конечно, регулярные выражения с первого вида — это какой-то кошмар, но реально — ничего сложного нет. Просто вы еще пока не то, что не знаете (хотя это так), но вы еще даже не подошли к осознанию проблемы — «для чего это вообще нужно!?» Так что наберитесь терпения, скоро вы неплохо начнете разбираться в работе двигателя внутреннего сгорания внедорожника «Линукс».

В нашу последовательность команд осталось добавить один шаг. Нам ведь нужно получить не просто словарь слов на экране консоли, а желательно получить его в файл. Давайте перенаправим вывод в файл:

$ cat myfile.txt | tr -c '[:alnum:]' '\n*' | sort -iu | grep -v '^[0-9]*$' > mywords.txt

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

Вот смотрите, допустим, мне надо посчитать выражение «2 * 3 + 4» и передать результат далее по цепочке вычислений. Я напишу так

$ echo "2 + 3 * 4" | bc

После исполнения на экране консоли должно появитсья число 14. «Эка невидаль! Что тут такого сверхестественного?» — воскликнут нетерпеливые Виндузятники. И будут как всегда по-своему правы. А то?

Но ведь это же всего лишь пример. Причем пример, сознательно упрощенный до нельзя и оторванный от жизни.

Я все же расшифрую, что он делает. Команда echo передает символьную строку, заключенную в кавычки, на вход калькулятора. А калькулятор вычисляет результат и выдасе его в свой поток вывода.

Вместо команды echo вы можете использовать команду cat с указанием файла, содержимое которого cat передаст на вход калькулятора. Файл вы можете заготовить заранее и как-нибудь его время от времени модифицировать…

Э-э… вы в детстве в кубики играли? У вас был какой-нибудь конструктор на подобие Лего? Вы улавливаете дух Линукса?

Специфика же Виндовса состоит несколько в другом. Она заключается в том, чтобы предоставить пользователю закрытый универсальный инструмент с обширной функциональностью. Эдакий швейцарский перочинный ножик. И не просто предоставить, а так предоставить, чтобы у пользователя не было никакого другого выбора кроме как купить. С точки зрения бизнеса — это нормально. Но сточки зрения теории создания программ — это вред и стрельба по целям, не связанным с функциональным назначением программы.

Основная цель программ в Виндовсе — получение прибыли. И только потом — удовлетворение потребностей пользователя. В Линуксе наоборот: основная цель создания программ — удовлетворение потребностей, и уже только потом — получение прибыли. Как говорится, почувствуйте разницу в подходе создания программ.

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

Однако стоит только проронить слово об этом ножике в среде профессионалов (например, автомехаников), вас тут же поднимут на смех! Ножницы, говорите? — Ну-ну! Отвертка? — Ха-ха! Ни на один инструмент нельзя положиться.

Так и с Вендовыми программами — универсально, но … «спасибо не надо! Сувенирные инструменты (для пользователей-хомячков) не интересуют!» С этими инструментами всё как-то не так. Вроде есть инструмент, но толком использовать не получается. Или, что еще чаще бывает, — инструмент используется на 5%.

Недавно слышал фразу — «зачем же жениться на всей девушке, если понравились только ямочка на ее щеке?» Почему я должен платить за весь Фотошоп, если я только и умею убирать «красные глазки»? Про запас говорите? Про какой запас? Вы много знаете людей, которые профессионально на все 100% используют свои виндовые программы?

Сплошь и рядом в офисах сидят хомячки, которые знают Ворд-Иксель и Косынку. А так же умеют круто писать в Ворде жирными и наклонными буквами. И пожалуй, это всё! Назовите процент использования функциональности Ворда? Фотошопа? Нэро? Вы улавливаете суть происходящего?

Если вендовая прога ведет себя как-то не так, то обычно сделать ничего нельзя — исходников-то нет. Да и знаний по проге — почти никаких. Многие нужные ее параметры зашифрованы и глубоко спрятаны в Реестре. Поди —разберись! Как вы думаете, по какой причине в Гугле столько много вопросов, которые начинаются на «как крякнуть программу»?

Мало того, каждая такая многофункциональная программа дублирует часть функций другой многофункциональной программы. Дублирует со своими прибабахами, своим подходом и своими особенностями. Из-за того что в программах заложена избыточная (я бы сказал — лишняя, не нужная, про запас!) функциональность, программы большие. Огромные! Помните, я чуть выше говорил, что чем больше программа по объему, тем сложнее ее отлаживать? Намек ясен?

У вендузятников даже есть особая гордость — умение использовать инструмент не по назначению. Звучит одиозно. Все равно что «я умею ковырять отверткой в ухе и резать хлеб ножовкой по металлу.» Я бы еще понял, если бы это происходило на фоне отсутствия предназначенных для этого инструментов.

На практике же получается, что самый писк это тогда, когда ученик строит таблицы и производит табличные вычисления в Word-е, текст набирает и форматирует в графическом редакторе, а рисунки делает в Excel-е. Все поставлено с ног на голову! И это считается не только правильно, это —  считается круто! Высший пилотаж! Программы же позволяют это делать — значит надо уметь.

Хорошо. Это происходит на стороне пользователей. А что есть на стороне Виновс-программистов? Им-то что делать? Ведь у них требования отнюдь не сделать программу как можно проще и лучше. У них противоположные требования.

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

Ну, право же! И в самом деле, какой же дурак согласится отдать деньги за простенькую программку? Поэтому в программу пихается все что надо и не надо. Программа жиреет со всеми вытекающими отсюда последствиями. Вы понимаете куда ведет эта дорога?

Ну вот, пожалуй это все, что я хотел сказать про программируемый калькулятор командной строки. Я не ставил себе задачу дать исчерпывающие сведения по этой программе. Все, что я хотел, — это чтобы вы обратили на эту программу свое внимание. Поигрались с ней и определили для нее место в своем арсенале. Если вас заинтересовал этот калькулятор, то вы можете вызвать его описание:

$ man bc

и не забываете погуглить. В интернете полно информации по этому калькулятору. А вообще, долго на нем не застревайте с программированием. Как только почувствуете, что программирование вас затягивает, скорее пересаживайтесь на Python.

Если что, спрашивайте. Попробую ответить на ваши вопросы.

7 responses to “Вычисления в Линуксе

  1. Ну вот, нашел досадную недоработку, не считает дробные степени, причем парсер до обидного глупый, например, 100^(1/2) = 1, так как считает 100^1, а 100^0.5 вообще выдает ошибку. Поэтому я и дальше буду пользоваться браузерным калькулятором Cloudy Calculator (плагин под Chrome).

    • да. есть такой момент. bc — это не совсем тот калькулятор, к которому мы все привыкли. Поэтому мы ожидаем от bc точно такого же поведения, а его, естественно нет. Обманутые надежды выливаются в обиды на инструмент: «Ваш дурацкий Линукс — это унылое г. Винда лучше.» и так далее.

      Есть определенные ограничения, и есть методы, которые позволяют эти ограничения красиво обходить. Я просто еще не успел рассказать обо всех тонкостях и прелестях этого калькулятора.

      В двух словах — не требуйте от вещей и людей не свойственной им функциональности. Не требуйте от Линукса Вендового поведения, Вендовой функциональности. Он другой. Он совершенно другой. С ним надо иначе работать. А если попытаетесь работать в Лине как в Венде, то и получите соответственную дисфункцию. Аналогично, если вы попытаетесь работать с любым другим инструментом, например, с этим калькулятором, согласно своему убеждению, ты вы обязательно нарветесь на неудобства и проблемы.

      Показатель степени для этого калькулятора — должно быть целое число. Если Вам нужна степень из множества действительных чисел, или, тем более — комплексных, ну так! Вы ж наверняка прослушали курс «вышки» (высшей математики), и Вас не должно затруднить выполнить свою задачу другим способом. А вот как это красиво сделать, я расскажу чуть позже. Как раз прелесть этого калькулятора заключается в том, что он — программируемый! Вы один раз пишите свою функцию, добавляете ее в калькулятор, и Ваш прокачанный калькулятор работает так, как Вам нужно.

      А вообще, количество самых разнообразных программ-калькуляторов достаточно большое, несколько десятков. Идеального калькулятора не существует. Какие-то из них лучше выполняют определенные действия, иные — хуже. Панацеи нет. А с другой стороны, каждый мастер выбирает инструмент себе сам. Я вас не агитирую использовать всегда и везде именно этот калькулятор. Я всего-лишь говорю «Смотрите, какой есть калькулятор! С ним можно работать вот так и вот так».

      Но все равно, спасибо вам за замеченную особенность. При дальнейшем повествовании в статье я уделю чуть больше внимания этому моменту. Покажу, как правильно это делать.

  2. Большое спасибо за статью, очень познавательно 😉

    • А Вам спасибо за отзыв.

      И на самом деле, приятно слышать такие отзывы — что мой труд не напрасный.

      • И я хочу поблагодарить Вас за статьи. Огромное спасибо Вам за то, что подогреваете интерес к различным темам.

        Благодаря вот этой статье я теперь считаю прямо в текстовом редакторе (http://ibnteo.klava.org/2012/11-02-wcalc). Недавно решил научиться считать на логарифмической линейке, как-то пропустил их в своей жизни, для этого купил и получил в подарок обычные линейки и круглую КЛ-1, очень понравилась идея быстрого аналогового счёта с определённой точностью вычислений. И вообще теперь хочу подтянуть забытые математические знания, начиная с тригонометрии, и заканчивая интегралами (или не заканчивая, а только начиная). Начал разрабатывать программируемый калькулятор на Forth, с полноценной клавиатурой для одной руки, скорее всего калькулятор будет собран на MSP430.

      • Ну, что сказать… похвально, похвально!
        Уважаю людей, одержимых какой-нибудь сумасшедшей идеей. Уважаю тех, кто пришел в ЭТОТ мир исследовать его строение, изучать его законы, а тупо рубить бабло.

  3. Спасибо за статью. Очень познавательно и интересно!

Оставьте комментарий