В Linux команда dc
используется для вычисления арифметических выражений неограниченной точности и оценки их в форме постфиксного выражения.
Содержание
- Основы
- Синтаксис
- Параметры
- Команды печати
- Арифметика
- Управление стеком
- Регистры
- Примеры использования в Linux команды dc
- Заключение
Основы
Утилита позволяет определять и вызывать макросы. Этот калькулятор читает со стандартного ввода; если ему переданы какие-либо аргументы команды, это имена файлов, и dc
считывает и выполняет содержимое файлов перед чтением со стандартного ввода
Весь обычный вывод осуществляется в стандартный вывод; все выходные данные ошибок относятся к стандартной ошибке.
Калькулятор с обратной полировкой хранит числа в стеке. Ввод числа помещает его в стек. Арифметические операции извлекают аргументы из стека и отправляют результаты.
Для ввода числа в dc
вводятся цифры (используются заглавные буквы от A до F как «цифры» при работе с базой ввода больше десяти) с необязательной десятичной точкой.
Экспоненциальная запись не поддерживается. Чтобы ввести отрицательное число, начните его с _
(подчёркивание). -
(тире или дефис) для этого использовать нельзя. Для ввода двух чисел подряд их следует разделить пробелами или символами новой строки. Они не имеют никакого значения как команды.
Ввод числа помещает его в стек, а ввод оператора оценивает выражение и помещает результат обратно в стек. Он может оценивать +
, -
, /
, *
, %
, ^
. Для управления стеком можно использовать различные команды.
Синтаксис
$ dc [опция] [файл ...]
Параметры
-e, --expression=EXPR
Оценить выражение
-f, --file=FILE
Оценить содержимое файла
-h, --help
Отобразить эту справку и выйти
-V, --version
Вывести информацию о версии и выйти
Команды печати
p
Печатает значение на вершине стека, не изменяя стек. После значения печатается новая строка
n
Печатает значение в верхней части стека, извлекая его, и не печатает новую строку после этого
P
Извлекает значение из вершины стека. Если это строка, она печатается без завершающего символа новой строки. В противном случае это число, и целая часть его абсолютного значения выводится как base (UCHAR_MAX+1) поток байтов. Предполагая, что (UCHAR_MAX+1) равно 256 (как это происходит на большинстве машин с 8-битными байтами), последовательность KSK0k1/_1Ss [ls*]Sxd0>x [256~Ssd0qaPlxx] dsxxsx0sqLqsxLxLK+k также может выполнять эту функцию. (Большая часть сложности приведённого выше кода связана с вычислением символов в обратном порядке и желанием гарантировать, что все регистры вернутся в исходное состояние)
f
Печатает все содержимое стека, ничего не изменяя. Это хорошая команда, которую можно использовать, если вы заблудились или хотите выяснить эффект команды
Арифметика
+
Извлекает два значения из стека, складывает их и помещает результат. Точность результата определяется только значениями аргументов, и ее достаточно, чтобы быть точным
-
Извлекает два значения, вычитает первое извлечённое из второго извлечённого и отправляет результат
*
Извлекает два значения, умножает их и отправляет результат. Количество цифр дроби в результате зависит от текущего значения точности и количества цифр дроби в двух аргументах
/
Извлекает два значения, делит второе полученное значение на первое и отправляет результат. Количество цифр дроби определяется значением точности
%
Извлекает два значения, вычисляет остаток от деления, который сделала бы команда
/
, и отправляет его. Вычисленное значение такое же, как и значение, вычисленное последовательностью Sd dld/ Ld*-~
Извлекает два значения, делит второе полученное значение на первое полученное. Полученное частное помещается первым, а затем остаток. Количество цифр дроби, используемых при делении, определяется значением точности. (Последовательность SdSn lnld/LnLd% также может выполнять эту функцию, но с немного другой проверкой ошибок)
^
Извлекает два значения и возводит в степень, используя первое значение в качестве показателя степени, а второе значение в качестве основания. Дробная часть показателя игнорируется. Значение точности указывает количество цифр дроби в результате
|
Извлекает три значения и вычисляет модульное возведение в степень. Первое полученное значение используется в качестве модуля приведения; это значение должно быть ненулевым числом и должно быть целым числом. Второе вытолкнутое значение используется в качестве показателя степени; это значение должно быть неотрицательным числом, и любая дробная часть этого показателя игнорируется. Третье полученное значение — это возведённое в степень основание, которое должно быть целым числом. Для маленьких целых чисел это похоже на последовательность Sm^Lm%, но, в отличие от
^
, эта команда работает с произвольно большими показателямиv
Извлекает одно значение, вычисляет его квадратный корень и отправляет его. Значение точности указывает количество цифр дроби в результате
На большинство арифметических операций влияет «значение точности», которое можно установить с помощью команды k
. Значение точности по умолчанию равно нулю, что означает, что все арифметические действия, за исключением сложения и вычитания, дают целочисленные результаты.
Управление стеком
c
Очищает стек, опустошая его
d
Дублирует значение на вершине стека, помещая еще одну его копию. Таким образом, 4d*p вычисляет 4 в квадрате и печатает его
r
Меняет порядок (меняет местами) два верхних значения в стеке. (Этого также можно добиться с помощью последовательности SaSbLaLb)
Регистры
Утилита dc
предоставляет как минимум 256 регистров памяти, каждый из которых имеет односимвольное имя. Вы можете сохранить число или строку в регистре и получить их позже.
sr
Извлеките значение из вершины стека и сохраните его в регистр r
lr
Скопируйте значение в регистр r и поместите его в стек. Это не меняет содержимое r
Каждый регистр также содержит свой стек. Текущее значение регистра является вершиной стека регистров.
Sr
Извлеките значение из вершины (основного) стека и поместите его в стек регистра r. Предыдущее значение регистра становится недоступным
Lr
Извлеките значение из вершины стека регистра r и поместите его в основной стек. Предыдущее значение в стеке регистра r, если таковое имеется, теперь доступно с помощью команды lr
Примеры использования в Linux команды dc
Вход в калькулятор
oleg@mobile:~:$ dc
Приглашение dc
представляет собой пустую строку, и оно готово принять наши команды.
Ввод числа в стек
Помещаем в стек число 1234:
oleg@mobile:~:$ dc
1234
Воспользуемся f
для отображения всего содержимого стека:
oleg@mobile:~:$ dc
1234
f
1234
Выведено 1234.
Умножение
Итак, число 1234 находится в стеке и готово к работе. Умножим его на 2 и выведем результат. Команда dc
использует обратную (постфиксную) нотацию, в которой операнды размещаются первыми, а операторы – вторыми:
oleg@mobile:~:$ dc
1234
f
1234
2*p
2468
Выведен результат 2468.
Сложение
Сложим число 2468, полученное в предыдущем примере, с числом 532:
oleg@mobile:~:$ dc
1234
2*p
2468
532+p
3000
Вычитание
Из числа 3000, полученного в предыдущем примере, вычтем 1000 и выведем результат:
oleg@mobile:~:$ dc
1234
2*p
2468
532+p
3000
1000-p
2000
Деление
Разделим полученное в предыдущем примере число 2000 на 2 и выведем результат:
oleg@mobile:~:$ dc
1234
2*p
2468
532+p
3000
1000-p
2000
2/p
1000
Извлечение корня
Теперь из числа 1000, полученного в предыдущем примере, извлечём квадратный корень:
oleg@mobile:~:$ dc
1234
2*p
2468
532+p
3000
1000-p
2000
2/p
1000
vp
31
Точность вычислений
Точность извлечения квадратного корня в предыдущем примере вряд ли кого-либо устроит, так как по умолчанию она равна 0 (вычисляется ноль знаков после запятой).
Точность вычислений можно установить любой, но, конечно, не следует доводить её до полной нелепицы.
Укажем утилите большую точность с помощью команды k
:
oleg@mobile:~:$ dc
10k1000vp
31.6227766016
Здесь мы объединили несколько операций в одну команду, которая выполнила операции в следующем порядке:
- поместила 10 в стек;
- сказала k извлечь это число из стека и установить точность до 10 десятичных знаков;
- поместила 1000 в стек;
- сказала v извлечь 1000 из стека, вычислить квадратный корень и поместить результат в стек;
- вывела результат с помощью p.
Выход из калькулятора
Теперь выйдем из dc
, нажав клавишу q:
oleg@mobile:~:$ dc
10k1000vp
31.6227766016
q
oleg@mobile:~:$
Заключение
Внимательно прочитав эту статью о базовых примерах использовании в Linux калькулятора dc
вы сможете самостоятельно овладеть и другими операциями.