Производственно-внедренческий кооператив

"И Н Т Е Р Ф Е Й С"













Диалоговая Единая Мобильная

Операционная Система

Демос/P 2.1










Программы для вычисления

с произвольной точностью

bc и dc












Москва

1988















АННОТАЦИЯ

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

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

1. ВВЕДЕНИЕ

bc - это язык и компилирующая программа для выполнения
арифметических операций с произвольной точностью в операци-
онной системе ДЕМОС.

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

Имеется свойство масштабирования, которое позволяет
использовать запись с десятичной точкой, а также возможность
для ввода и вывода чисел в системах счисления, отличных от
десятичной. Числа могут быть переведены из десятичной сис-
темы счисления (например, в восьмеричную) просто установкой
выходного основания системы счисления в 8.

Доступен небольшой набор библиотечных функций, таких
как sin, cos, arctan, log, exp и функции Бесселя целочислен-
ного порядка.

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

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

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

Синтаксис языка bc в значительной мере похож на синтак-
сис языка Си. Те, кто знаком с языком Си, легко освоят язык
bc.














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

Компилятор bc воспринимает программы, написанные на
языке bc и компилирует вывод, который интерпретируется прог-
раммой dc. Некоторые из команд, о которых рассказывается в
описании dc, были разработаны для взаимодействия компилято-
ров и трудны для восприятия человеком.

Числа, которые вводятся в dc, помещаются в стек.
Команды dc производят действия над двумя верхними числами в
стеке и помещают результат обратно в стек.

Если в командной строке ДЕМОС указан аргумент, который
является именем файла, то сначала считывается этот файл или
файлы, а затем ввод переключается на стандартный (клавиатуру
терминала).

2. ИНТЕРАКТИВНЫЙ КАЛЬКУЛЯТОР bc

2.1. Простые действия с целыми числами

Простейшим типом выражения является арифметическое
выражение в самой строке. Например, если вы введете строку:

123456789+987654321

программа почти мгновенно выдает ответ:

1111111110


Могут использоваться следующие операции +, -, *, /, %,
и ^, которые означают действия сложения, вычитания, умноже-
ния, деления, определения остатка и возведения в степень
соответственно. Результатом деления целых чисел является
целое число без дробной части. При делении на ноль появля-
ется сообщение об ошибке.

Перед любым членом выражения может стоять знак минус,
который указывает на то, что данный член отрицателен (унар-
ный знак минус). Выражение:

1985+-R68

означает, что число -68 должно быть добавлено к числу 1985.

Более сложные выражения с несколькими операциями и
скобками интерпретируются также как и в Фортране. Операция


- 3 -










^ (возведение в степень) имеет наибольший приоритет выполне-
ния, затем следуют операции * (умножение), % (нахождение
остатка), / (деление) и наконец, операции + (сложение) и -
(вычитание). В первую очередь оценивается содержимое выраже-
ний, стоящих в скобках. Возведение в степень выполняется
справа налево, а остальные операции слева направо. Следую-
щие два выражения:

a^b^c и a^(b^c)

эквивалентны, также как эквивалентны и выражения:

a*b*c и (a*b)*c


Для запоминания чисел используются внутренние регистры
(переменные), которые имеют имена, состоящие из одной строч-
ной латинской буквы. Регистру может быть обычным способом
присвоено значение выражения. Выражение:

s=s+10

выполняет увеличение на 10 значения, содержащегося в
регистре с именем s. Если, как и в данном случае, самым
внешним является оператор =, то осуществляется присваивание,
но результат не печатается. Разрешается использовать не
более 26 регистров.

Имеется встроенная функция извлечения квадратного корня
(sqrt), причем дробная часть результата отбрасывается
(вычисления с большей точностью описаны в разделе "Масштаби-
рование"). Если ввести следующие строки

q=sqrt(624)
q

то напечатается результат

24


2.2. Основания систем счисления

Существуют специальные внутренние переменные, называе-
мые ibase и obase. Содержимое ibase, первоначально установ-
ленное в 10, определяет основание системы счисления, исполь-
зуемое для вводимых чисел. Например, в результате выполнения
следующих строк:

ibase=9
11

появится выходная строка:


- 4 -










10

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

ibase=10

так как число 10 будет интерпретироваться как девятиричное,
и входное основание останется без изменения.

Чтобы работать в шестнадцатиричной системе счисления,
используются символы A-F для обозначения цифр 10-15, соот-
ветственно. Использование символов A-F разрешается в
качестве чисел независимо от того, какая система счисления
установлена в данный момент.

Выражение

ibase=A

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

Содержимое obase первоначально установленное в 10,
используется, как основание для выводимых чисел. Так, напри-
мер, введя строки

obase=16
654321

получим в результате

9FBF1

что является, как мы и хотели, пятизначным шестнадцатиричным
числом. Очень большие выходные основания допустимы, и они
иногда бывают полезны. Например, большие числа могут быть
выведены в группах по три цифры, если установить obase в
1000. Например, если ввести следующие строки

obase=1000
1234567890987654321234567890

то результат напечатется в виде

1 234 567 890 987 654 321 234 567 890

Необычные (т.е. 1, 0 или отрицательные) основания также
воспринимаются.


- 5 -










Очень большие числа расщепляются при выводе на печать
по 70 символов на строку. Строки, не являющиеся последними,
оканчиваются символом \. Десятичный результат выводится
практически мгновенно, но вывод очень больших чисел (т.е.
более чем 100 цифр) с другими основаниями происходит
довольно медленно. Вывод в недесятичных основаниях осуществ-
ляется примерно со скоростью 100 цифр за шесть секунд.

Рекомендуем запомнить, что на процесс внутренних вычис-
лений ibase и obase не влияют, так как вычисления выполня-
ются в десятичной системе счисления, а ibase и obase исполь-
зуются только во время перевода в нужную систему счисления
при вводе и выводе, соответственно.

2.3. Масштабирование

Еще одна специальная внутренняя переменная, называемая
scale используется для того, чтобы определить количество
знаков после запятой при вычислениях. Числа могут содержать
до 99 десятичных цифр после запятой. Это количество знаков
сохраняется в дальнейших вычислениях до тех пор, пока не
будет изменено.

Когда над двумя масштабированными числами производится
одно из арифметических действий, результат имеет точность,
определяемую следующими правилами. Для сложения и вычитания
точность результата - большая из точности операндов. В этом
случае результат никогда не усекается. Для умножения точ-
ность результата никогда не меньше, чем максимум точностей
двух операндов, и не больше, чем сумма точностей операндов.
Точность частного равна значению внутренней переменной
scale. Точность остатка есть сумма точностей частного и
делителя. Результат возведения в степень масштабируется так
же, как и при умножении. Показатель степени должен быть
целым. Точность квадратного корня устанавливается максималь-
ной из точности аргумента и scale.

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

Содержимое scale должно быть не больше 99 и не меньше
нуля. Первоначально она устанавливается в 0. В случае,
когда требуется более 99 дробных цифр, вы можете приспосо-
бить свое собственное масштабирование.

Внутренние переменные scale, ibase, obase могут исполь-
зовться в выражениях также как и другие переменные. Строка

scale=scale+1

увеличивает значение scale на единицу а строка



- 6 -










scale

вызывает печать значения scale.

При вычислениях значение scale используется, как коли-
чество десятичных цифр, даже если ibase и obase не равны 10.
Напомним еще раз, что внутренние вычисления производятся в
десятичной системе счисления, а перевод в нужную систему
счисления осуществляется при вводе и выводе числа.

2.4. Функции

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

define a(x){

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

return
return(x)

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

Переменные, используемые в функциях, могут быть объяв-
лены, как автоматические, используя выражение типа

auto x,y,z

В функции может быть только одно выражение auto, и оно
должно быть первым в определении. Автоматические переменные
размещаются в памяти и инициализируются в ноль при входе в
функцию и сбрасываются при выходе из нее. Значения любых
переменных с именами, совпадающими с именами переменных в
функции, не портятся, так как переменные в функциях являются
локальными. Функции могут быть вызваны рекурсивно, и автома-
тические переменные на каждом уровне вызова защищены. Имена
параметров в определении функции обрабатываются таким же
образом, что и автоматические переменные с единственным иск-
лючением, что им присваиваются конкретные значения при входе
в функцию. Пример определения функции:






- 7 -










define f(x,y){
auto z

    z

=x*y
return(z)
}

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

Функция вызывается при появлении ее имени, за которым
следуют аргументы, заключенные в скобки и разделенные запя-
тыми. Если использовалось неверное число аргументов, то
результат непредсказуем.

Функции без аргументов определяются и вызываются,
используя пустые скобки: p().

Если набрать строку

f(3.14159,2,71828)

где f - функция, которая была описана выше, то напечатается
результат:

8.53972

а если набрать

y=f(f(12,34),56)

то переменной y присвоится значение 22848.

2.5. Индексированные переменные

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

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

Имя массива может использоваться, как аргумент функции,
или может быть описано, как автоматическое в описании функ-
ции, используя пустые квадратные скобки:



- 8 -










p(c[])
define p(c[])
auto c[]


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

2.6. Управляющие операторы

Операторы if, while и for могут использоваться для
того, чтобы изменять порядок выполнения действий в программе
или вызвать повторение выполнения определенных последова-
тельностей. Тело каждого из этих операторов - это оператор
или составной оператор, состоящий из нескольких операторов,
заключенных в фигурные скобки. Они пишутся следующим обра-
зом:

if(условие) оператор
while(условие) оператор
for(выраж1;условие;выраж2) оператор

или

if(условие) {операторы}
while(условие) {операторы}
for(выраж1;условие;выраж2) {операторы}


Условие в любом из управляющих операторов - это выраже-
ние в форме

m>>n

где два выражения связаны одной из шести операций отношения:
<&lt;, >&gt;, <&lt;=, >&gt;=, == или !=. Отношение == означает эквива-
лентно, а отношение != означает не эквивалентно. Значение
остальных операций отношения ясно и так.

Будьте внимательны при использовании операций = и ==,
так как некорректное использование одной операции вместо
другой не может быть выявлено компилятором, а при использо-
вании первой произойдет присваивание, а при использовании
второй - сравнение.

Оператор if вызовет выполнение своего тела тогда и
только тогда, когда условие истинно. Затем управление пере-
дастся следующему оператору в последовательности.




- 9 -










Оператор while вызовет многократное выполнение своего
тела до тех пор, пока условие истинно. Условие проверяется
перед каждым выполнением тела, и, если условие ложно, управ-
ление передается оператору, следующему за телом оператора
while.

Оператор for начинается с выполнения выраж1. Затем про-
веряется условие, и, если оно истинно, выполняются операторы
в теле оператора for. Затем выполняется выраж2. Проверяется
условие и так далее. Типичное использование оператора for -
это управляемое повторение, такое, например, как в операторе

for(i=1;i<=20;i=i+2)i

который будет печатаь целые нечетные числа в интервале от 1
до 20. Далее представлены несколько примеров использования
управляющих операторов.

define f(n){
auto i, p

    p=1


for(i=1;i<=n;i=i+1) p=p*i
return(p)
}

Тогда, набрав строку

f(h)

получим печать значения факториала числа h, если h целое
положительное. А это определение функции, которая будет
вычислять значения биномиальных коэффициентов (предполага-
ется, что s и t - целые положительные).

define b(s,t){
auto i, p

    p=1


for(i=1;i<=t;i=i+1) p=p*(s-i+1)/i
return(p)
}

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












- 10 -










ные ошибки отбрасывания:

scale=25
define e(z){
auto a, b, c, d, n

    a=1


    b=1


    c=1


    d=0


    n=1


while(1==1){
a=a*z
b=b*n
c=c+a/b
n=n+1
if(c==d) return(c)
d=c
}
}


2.7. Некоторые детали

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

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

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

(y=y+123)

то произойдет не только указанное присваивание, но и напеча-
тается результирующее значение.

А это пример использования значения оператора присваи-
вания, когда он не заключен в круглые скобки:

p=n[k=k*3]

В этом случае значение n будет присвоено переменной p, а
также k будет увеличено в три раза перед тем, как k будет
использовано как индекс.

Следующие конструкции работают в bc так же, как они
выполняются в языке Си. Подробнее указано в "Детальном опи-




- 11 -










сании" или в руководстве по языку Си.

x=y=z то же, что и x=(y=z)
x=+y x=x+y
x=-y x=x-y
x=*y x=x*y
x=/y x=x/y
x=%y x=x%y
x=^y x=x^y
x++ (x=x+1)-1
x-- (x=x-1)-1
++x x=x+1
--x x=x-1


ПРЕДУПРЕЖДЕНИЕ! В некоторых из этих конструкций сущест-
венно наличие или отсутствие пробелов. Существует различие
между a=-b и a= -b. В первом случае переменной a будет
присвоено значение a-b", а во втором -b.

2.8. Три важные вещи

1. Чтобы выйти из программы bc наберите quit.

2. Имеется возможность вводить комментарий, так же, как и в
языках Си и ПЛ/1. Комментарий начинается с "/*" и окан-
чивается "*/".

3. Имеется библиотека функций, которая может быть использо-
вана, если набрать при вызове команды bc

bc -l

Эта команда вызовет загрузку небольшгого набора библио-
течных функций, который содержит: синус (назвается s),
косинус (c), арктангенс (a), натуральный логарифм (l),
экспоненту (e) и функцию Бесселя целого порядка
(j(n,x)"). Несомненно, что будут написаны и другие функ-
ции. Эта библиотека устанавливает точность, равную 20
знакам после запятой. Вы можете переустановить ее, если
вам надо.

Bсли вы наберете

bc файл ...

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




- 12 -










2.9. Детальное описание

2.9.1. Обозначения

На следующих страницах синтаксические категории обозна-
чаются строчными русскими буквами, выделенными курсивом
(например выражение); ключевые слова - жирными латинскими
(например scale); то, что находится в квадратных скобках
является необязательным.

2.9.2. Знаки

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

2.9.2.1. Комментарии

Комментарии начинаются символами /* и кончаются симво-
лами */.

2.9.2.2. Идентификаторы

Имеется три вида идентификаторов - обычные идентифика-
торы, идентификаторы массивов и идентификаторы функций. Все
три типа имеют имена, состоящие из единственной строчной
латинской буквы. После идентификатора массива следуют квад-
ратные скобки, возможно заключающие выражение, определяющее
индекс. Массивы одномерны и могут содержать до 2048 элемен-
тов. Индексирование начинается с нуля, поэтому массив может
иметь индексы от 0 до 2047. Значения индексов усекаются до
целого. За идентификатором функции следуют круглые скобки,
возможно содержащие аргументы. Имена трех типов идентифика-
торов не пересекаются: программа может иметь переменную z,
массив z и функцию z.

2.9.2.3. Ключевые слова

Следующие слова являются зарезервированными ключевыми
словами

ibase if
obase break
scale define
sqrt auto
length return
while quit
for






- 13 -










2.9.2.4. Константы

Константы состоят из произвольной длины чисел с необя-
зательной десятичной точкой. Допускаются также шестнадцати-
ричные цифры A-F, которые имеют значения 10-15, соответст-
венно.

2.9.3. Выражения

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

2.9.3.1. Простые выражения

2.9.3.1.1. Именованные выражения

Именованные выражения - это выражения, которые хранят
какое-либо значение. Проще говоря, именованные выражения -
левая часть оператора присваивания. Значение именованного
выражения - это значение, хранимое в именованном месте.

идентификаторы
Простые идентификаторы - это именованные выражения.
Они имеют начальное нулевое значение.

имя-массива[выражение]
Элементы массива - это именованные выражения. Они
имеют начальное нулевое значение.

scale, ibase и obase
Внутренние регистры scale, ibase и obase - это имено-
ванные выражения. scale - это количество цифр после
десятичной точки, которое используется в арифметических
действиях. scale имеет начальное нулевое значение.
ibase и obase - это основания систем счисления вводимых
и выводимых чисел, соответственно. Как ibase, так и
obase имеют начальное значение 10.

2.9.3.1.2. Вызовы функций

имя-функ.([выр.[,выр...]])
Вызов функции состоит из имени функции, за которым сле-
дуют круглые скобки, содержащие разделенный запятыми
список выражений, которые являются аргументами функции.
Допускается использовать, как аргумент, весь массив,
если при его определении за именем следуют пустые квад-
ратные скобки. Все аргументы функции передаются по
значению, поэтому изменения, производимые над формаль-
ными параметрами, не имеют воздействия на фактические.
Если функция прерывается выполнением оператора return,
то значение функции - это значение выражения в скобках


- 14 -










оператора return или нуль, если выражение отсутствует
или нет оператора return.

sqrt(выражение)
Результатом является квадратный корень из выражения.
Результат усекается до последней значащей десятичной
цифры. Точностью результата является большая величина
из точности выражения или scale.

length(выражение)
Результатом является общее число десятичных цифр в
выражении. Точность результата - ноль знаков после
запятой.

scale(выражение)
Результатом является точность выражения. Точность
результата - ноль знаков после запятой.

2.9.3.1.3. Константы

Констатнты - это простые выражения.

2.9.3.1.4. Круглые скобки

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

2.9.3.2. Унарные операции

Унарные операции выполняются справа налево.

-выражение
Результатом является выражение с противоположным знаком

++именованное выражение
Именованное выражение увеличивается на единицу.
Результатом является значение именованного выражения
после увеличения.

--именованное_выражение
Именованное выражение уменьшается на единицу. Резуль-
татом является значение именованного выражения после
уменьшения.

именованное_выражение++
Именованное выражение увеличивается на единицу.
Результатом является значение именованного выражения
перед увеличением.

именованное_выражение--
Именованное выражение уменьшается на единицу. Результа-
том является значение именованного выражения перед


- 15 -










уменьшением.

2.9.3.3. Операция возведения в степень

Операция возведения в степень выполняется справа
налево.

выражение^выражение
Результатом является первое выражение, возведенное в