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

                    "И Н Т Е Р Ф Е Й С"













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

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

                        Демос/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

        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. Операция возведения в степень Операция возведения в степень выполняется справа налево. выражение^выражение Результатом является первое выражение, возведенное в степень второго выражения. Второе выражение должно быть целым. Если a - это точность левого выражения, а b - абсолютное значение правого выражения (показателя сте- пени), то точность результата вычисляется по формуле min(a*b,max(scale,a)) 2.9.3.4. Операции группы умножения Операции *, /, % выолняются слева направо. выражение*выражение Результатом является произведение двух выражений. Если a и b - точности обоих выражений, то точность резуль- тата вычисляется по формуле min(a+b,max(scale,a,b)) выражение/выражение Результатом является частное от деления двух выражений. Точность результата - значение scale. выражение%выражение Операция % вырабатывает остаток от деления двух выраже- ний. Более точно, a%b - это a-a/b*b. Точность резуль- тата - это сумма точности делителя и значения scale. 2.9.3.5. Операции группы сложения Операции группы сложения выполняются слева направо. выражение+выражение Результатом является сумма двух выражений. Точность результата - это максимальная из точностей обоих выра- жений. выражение-выражение Результатом является разность двух выражений. Точность результата - это максимальная из точностей обоих выра- жений. - 16 - 2.9.3.6. Операторы присваивания Операторы присваивания выполняются справа налево. именованное_выражение=выражение Это выражение присваивает значение выражения справа именованному выражению слева. именованное_выражение=+выражение именованное_выражение=-выражение именованное_выражение=*выражение именованное_выражение=/выражение именованное_выражение=%выражение именованное_выражение=^выражение Результат указанных выше выражений эквивалентен именов. выр.=именов. выр. ОП выр. где ОП - знак операции после знака =. 2.9.4. Отношения В отличие от других операций, операции отношения допус- тимы только, как объекты операторов if, while или внутри оператора for. выражение<выражение выражение>выражение выражение<=выражение выражение>=выражение выражение==выражение выражение!=выражение 2.9.5. Классы памяти В bc имеется только два класса памяти - глобальный и автоматический (локальный). Командой auto требуется описы- вать только те идентификаторы, которые являются локальными для функций. Аргументы функций являются для них локальными. Все другие идентификаторы подразумеваются глобальными и дос- тупны для всех функций. Все идентификаторы - глобальные и локальные - имеют нулевое начальное значение. - 17 - Идентификаторы, описанные как auto, размещаются в памяти при входе в функцию и освобождаются при выходе из нее. Поэтому, они не сохраняют свое значение между двумя вызовами функции. Автоматические массивы определяются именем массива, за кото- рым следуют пустые квадратные скобки. 2.9.6. Операторы Операторы должны разделяться точкой с запятой или сим- волом новой строки. Операторы выполняются последовательно, за исключением тех случаев, где порядок указывается управля- ющими операторами. Операторы выражений Когда оператор есть выражение, если главный (внешний) оператор выражения не есть оператор присваивания, то печатается значение выражения, а за ним символ новой строки. Составные операторы Операторы могут быть объединены вместе, когда они окру- жены фигурными скобками {}. Строковые операторы, заключенные в кавычки "любая_строка" Этот оператор печатает то, что заключено в кавычки. Оператор if if(условие)оператор Если условие верно, то выполняется оператор. Оператор while while(условие)оператор Оператор выполняется до тех пор, пока условие истинно. Проверка условия осуществляется перед каждым выполне- нием оператора. Оператор for for(выраж.;условие;выраж.)оператор Оператор for выполняет те же действия, что и последова- тельность - 18 - первое_выражение while(условие){ оператор последнее_выражение } Все три выражения должны обязательно присутствовать. Оператор break break break вызвает прерывание выполнения операторов while или for Оператор auto auto идентификатор[,идентификатор] Оператор auto вызывает заведение значений идентификато- ров в стеке. Идентификаторы могут быть обычными иден- тификаторами или идентификаторами массива. Идентифика- тор массива определяется тем, что за именем массива следуют пустые квадратные скобки. Оператор auto должен быть первым оператором в определении функции. Оператор define define([параметр[,параметр...]]){ операторы} Оператор define определяет функцию. Параметры могут быть простыми идентификаторами или именами массивов. За именами массивов должны следовать пустые квадратные скобки. Оператор return return return(выражение) Оператор return вызывает окончание работы функции, изв- лечение из стека ее автоматических переменных и опреде- ление результата функции. Первая форма эквивалентна return(0). Результатом функции является результат выра- жения в скобках. Окончание работы Оператор quit останавливает выполнение программы bc и возвращает управление системе ДЕМОС в тот момент, когда он появляется. Оператор quit не может использоваться в определениях функций или в операторах if, for или - 19 - while. 2. ИНТЕРАКТИВНЫЙ СТЕКОВЫЙ КАЛЬКУЛЯТОР dc 2.1. Описание синтаксиса В данной главе описываются команды dc, которые предназ- начены для использования людьми. Дополнительные команды, которые предназначены для вызова компилятром, описаны в "Детальном описании". На строке допускается любое количество команд. Символы пробелов и новой строки игнорируются, исключая мест внутри чисел и тех мест, где ожидается имя регистра. Воспринимаются следующие конструкции: число Значение числа помещается в стек. Число - это непрерывае- мая цепочка цифр 0-9 и больших латинских букв A-F, которые рассматриваются как значения цифр 10-15, соответственно. Для обозначения отрицательного числа используется знак подчерк (_), который должен предшествовать числу. Числа могут содержать десятичную точку. + - * / % ^ Верхние два значения стека складываются (+), вычитаются (-), умножаются (*), делятся (/), ищется остаток от деле- ния первого на второе (%) или возводятся в степень (^). Два элемента извлекаются из стека, результат помещается обратно в стек, в его верхушку. Результат деления усека- ется до целого отбрасыванием дробной части. При возведе- нии в степень показатель степени должен быть целым. В детальном описании описывается, как работать с числами с десятичной точкой. sx Верхушка основного стека извлекается и запоминается в регистре с именем x, где x может быть любым символом. Если s - прописная буква, то x воспринимается как стек, и значение помещается в него. В имени регистра допускаются любые символы, даже пробелы или символы новой строки. - 20 - lx Значение регистра x заносится в стек. Значение регистра не изменяется. Если l - прописная буква, то x воспринима- ется как стек, и его верхнее значение извлекается и поме- щается в основной стек. Все регистры имеют начальное пустое значение, которое воспринимается как нулевое командой l и как ошибочное коман- дой L. d Дублируется значение верхушки стека. p Печатается верхнее значение стека. Верхушка остается без изменений. f Печатаются все значения в стеке и в регистрах. х Верхний элемент стека рассматривается как цепочка симво- лов, извлекается из стека и выполняется, как командная строка dc. [...] Помещает цепочку символов, заключенную в квадратные скобки в верхушку стека. q Выход из программы. Если q встретилось при выполнении цепочки, то уровень рекурсии уменьшается на два. Если q - прописная буква, то уровень вложенности стека уменьшается на величину верхушки стека. <&lt;х >&gt;х =х !<&lt;х !>&gt;х !=х Извлекаются и сравниваются два верхних элемента стека. Если установленное отношение справедливо, выполняется регистр х, Восклицательный знак означает отрицание. v Заменяется верхнее значение стека на его квадратный корень. Квадратный корень целого числа усекается до целого. Обработка чисел с десятичной точкой описывается в - 21 - детальном описании. ! Оставшаяся часть строки интерпретирутеся как команда ДЕМОС. Управление возвращается в программу dc, когда команда завершится. c Извлекаются все значения стека; стек очищается. i Извлекается верхнее знчение стека, которое рассматривается как основание системы счисления для последующих вводимых чисел. Если i - прописная буква, то значение основания системы счисления вводимых чисел заносится в стек. Осно- вания систем счисления меньше единицы и больше 16 не под- держиваются. o Извлекается верхнее значение стека, которое рассматрива- ется как основание системы счисления для последующих выво- димых чисел. Если o - прописная буква, то значение осно- вания системы счисления выводимых чисел заносится в стек. k Извлекается верхнее значение стека, и это значение исполь- зуется как точность вычислений, которая является количест- вом цифр после запятой при выполнении умножения, деления и возведения в степень. Точность должна быть больше либо равна нулю и меньше 100. Если k - прописная буква, то зна- чение точности заносится в стек. z Значение глубины стека заносится в стек. ? Строка ввода берется из исходного ввода (обычно консоль) и выполняется. 2.2. Детальное описание 2.2.1. Внутреннее представление чисел Числа запоминаются внутри, используя динамический расп- ределитель памяти. Числа хранятся в форме цепочек цифр в системе счисления с основанием 100 по одной цифре на байт - 22 - (сторичная цифра). Числа хранятся в порядке от младших цифр к старшим. Например, число 1234 имеет представление "34 12". После любой арифметической операции над числом тщательно проверяется, чтобы все цифры находились в интер- вале от 0 до 99 и не было лидирующих нулей. Число ноль представляется пустой цепочкой. Отрицательные числа представлены записью сторичного дополнения (цифры представлены как разность между 100 и соответствующей цифрой), которое аналогично записи двоичного дополнения для двоичных чисел. Самая старшая цифра отрица- тельного числа всегда -1, а все другие цифры в интервале 0-99. Цифра, предшествующая самой старшей цифре -1, никогда не может быть 99. Представление числа -157 во внутренней форме: "43 98 -1". Мы назовем эту форму канонической формой числа. Преимуществом этого представления является легкость сложения отрицательных чисел. Когда сложение выполняется цифра за цифрой, результат формально корректен. Результат только требует модификации, если необходимо, для перевода в каноническую форму. Так как наибольшее допустимое число 99, а в байте можно представлять вдвое большие числа, то сложение может выпол- няться с переносом. За самой старшей цифрой хранится дополнительный байт, показывающий число допустимых десятичных цифр после запятой. Представление числа .001: 1,3; число после запятой, показы- вает, что это число не есть значащая цифра. Значение этого дополнительного числа называется точностью числа. 2.2.2. Распределитель памяти Для внутреннего хранения чисел, команд и др. dc исполь- зует динамический распределитель памяти цепочек. Все считы- ваемые и записываемые числа проходят через этот распредели- тель. Взаимодействие с каждой цепочкой в распределителе происходит через четырехсловный заголовок, содержащий указа- тели на начало цепочки, ее конец, следующее место для записи и следующее место для чтения. Связь между распределителем и dc осуществляется через указатели к этим заголовкам. Распределитель первоначально имеет одну большую цепочку в списке свободных цепочек. Все заголовки, исключая один, указывающий на эту цепочку, имеются в списке свободных заго- ловков. Запросы на цепочки выполняются по размеру. Размер фактически выделяемой цепочки, есть ближайшая следующая сте- пень двойки. Когда выполняется запрос на цепочку, распреде- литель сперва проверяет свободный список, чтобы увидеть, есть ли там цепочка нужного размера. Если ничего не найдено, распределитель ищет более длинную цепочку и расщепляет ее до тех пор, пока не получится цепочка нужного размера. Оставша- яся часть цепочки помещается в свободный список. Если не - 23 - имеется цепочек большего размера, распределитель пытается объединить свободные цепочки меньшего размера в одну боль- шую. Так как все цепочки являются результатом расщепления больших цепочек, каждая цепочка имеет соседнюю с ней в памяти и, если соседняя цепочка свободна, то, чтобы увели- чить цепочку, можно требуемую цепочку объединить с соседней. При безуспешной попытке найти цепочку подходящей длины после объединения, распределитель запрашивает у системы сво- бодное место. Количество памяти в системе является единст- венным ограничением на размер и количество цепочек в dc. В распределителе имеются программы для чтения, записи, копирования цепочек, сдвига в начало, сдвига вперед на шаг и сдвига назад на шаг по цепочкам. Все манипуляции с цепоч- ками выполняются, используя эти программы. Программы чтения и записи увеличивают указатель чтения или указатель записи так, что символы цепочки читаются или пишутся подряд сериями вызовов чтения или записи. Указатель записи является, по существу, указателем на конец содержащей информацию части цепочки и при попытке прочитать информацию, находящуюся за этим указателем, чтение окажется безуспешным, а программа чтения в качестве ответа вернет признак конца цепочки. Попытка записать за конец цепочки вынудит распреде- литель запросить большее пространство и затем скопировать старую цепочку в больший блок. 2.2.3. Внутренняя арифметика Все арифметические действия выполняются в целых числах. Операнды (или операнд), требующиеся для выполнения действия извлекаются из главного стека и у них отбрасывается точ- ность, хранящаяся вместе с числом. Для того, чтобы получить результат выполнения программ внутренней арифметики с подхо- дящей точностью, к операндам добавляются нули или отбрасыва- ются лишние цифры. Например, если точность операндов раз- лична, и требуется выравнивание, как это бывает при сложе- нии, к операнду с меньшей точностью добавляются нули. После выполнения требуемой арифметической операции перед тем, как занести результат в стек, в конец числа добавляется значение его точности Регистр, называемый scale, используется в большинстве арифметических операций; scale определяет количество деся- тичных цифр в арифметических вычислениях. Значение scale может быть установлено в величину, расположенную в верхушке стека, с помощью команды k. Для того, чтобы занести значение scale в стек, используется команда K. scale должно быть не меньше нуля и меньше 100. При описании каждой арифметической операции будет показано точное влияние scale на вычисления. - 24 - 2.2.4. Сложение и вычитание Точности представления двух чисел сравниваются, и к числу с меньшей точностью добавляются последующие нули для того, чтобы уравнять точости обоих чисел. Если разница точ- ностей нечетна, то число с меньшей точностью умножается на 10. Точность результата устанавливается затем в величину, равную большей из двух точностей. Вычитание производится инвертированием знака числа для того, чтобы вычитание заменить на сложение. Сложение выполняется цифра за цифрой, начиная с младших разрядов к старшим. Перенос распространяется обычным спосо- бом. Результирующее число берется в канонической форме, при которой может потребоваться убрать лидирующие нули или, для отрицательных чисел, заменить старшие цифры "99 -1" на "-1". В любом случае цифры, которые не попадают в интервал 0-99, должны быть приведены в этот интервал, путем распространения переноса или заимствования из других разрядов. 2.2.5. Умножение Точности двух операндов запоминаются и отбрасываются. Оба операнда делаются положительными. Затем выполняется умножение способом цифра за цифрой. Первое число умножается на каждую цифру второго числа, начиная с младшего разряда. Промежуточные результаты накапливаются в частные суммы, сум- мирование которых дает окончательный результат. Результат заносится в канонической форме, а его знак определяется из знаков операндов. Точность результата устанавливается равной сумме точ- ностей двух операндов. Если эта точность больше, чем значе- ние внутреннего регистра scale, а также больше, чем точности обоих операндов, то точность результата устанавливается в максимальное из этих трех значений. 2.2.6. Деление Точности обоих операндов отбрасываются. У делимого отб- расываются лишние цифры или добавляются недостающие нули, чтобы сделать точость результата целого деления равной зна- чению внутренней переменной scale. Знаки запоминаются и отбрасываются. Деление выполняется также, как если бы оно выполнялось вручную. Вычисляется разница длин обоих чисел. Если дели- тель длиннее делимого, возвращается значение ноль. В против- ном случае две старшие цифры делимого делятся на старшую цифру делителя. Результат этого действия используется как первая (старшая) цифра частного. Пробная цифра умножается на делитель, и результат вычитается из делимого, и для - 25 - получения очередной цифры частного процесс повторяется до тех пор, пока остаток делимого не станет меньше делителя. В конце процесса цифры частного переводятся в каноническую форму и, если это необходимо, происходит распространение переноса. Знак определяется из знаков обоих операндов. 2.2.7. Нахождение остатка Для нахождения остатка вызывается программа деления, и выполняется деление так, как это было описано в предыдущем разделе. Возвращаемый результат - есть остаток от деления после завершения процесса деления. Знак остатка имеет такой же знак, что и делимое. Точность остатка устанавливается в максимальную из величин точности делимого и точности част- ного плюс точность делителя. 2.2.8. Вычисление квадратного корня Из операнда убирается точность. Если необходимо, дoбавляются нули для того, чтобы получить в результате тре- буемую точность. Для вычисления используется метод Ньютона с последующей апроксимацией по правилу: x[n+1] = 1/2 (x[n] + y / x[n]) Начальное предположение берется из расчета, что квадратный корень равен старшим двум цифрам. 2.2.9. Возведение в степень Разрешается возведение в степень только с целым показа- телем степени. Если показатель степени равен нулю, то результат равен единице. Если показатель степени отрицате- лен, то он делается положительным, а на основание делится единица. Шкала результата отбрасывается. Целый показатель степени рассматривается как двоичное число. Основание последовательно возводится в квадрат, а результат получается как произведение результатов этих воз- ведений основания, которые соответствуют позициям в двоичном представлении показателя степени. Чтобы сделать точность результата такой же, как и при умножении (которое на самом деле и выполнялось), отбрасывается необходимое количество цифр. 2.2.10. Перевод вводных чисел и входная система счисления Числа преобразуются во внутреннее представление по мере их считывания. Точность хранится с числом и является коли- чеством десятичных цифр после запятой. Перед отрицательными числами ставится знак "_" (подчерк). Шестнадцатиричные цифры A-F соответствуют числам 10-15, независимо от входного основания системы счисления. Для изменения основания системы счисления вводимых чисел используется команда i. Эта - 26 - команда извлекает из стека, усекает результирующее число до целого и использует его как основание системы счисления для последующего ввода чисел. Первоначально входная система счисления - десятичная. Команда I заносит значение основа- ния системы счисления вводных чисел в стек. 2.2.11. Выводные команды Команда p вызывает печать верхушки стека. При этом вер- хушка стека не извлекается. Для того, чтобы вывести содержи- мое всех внутренних регистров и всего стека, используется команда f. Для того, чтобы изменить основание системы счис- ления выводных чисел, используется команда o. По этой команде извлекается верхушка стека, усекается до целого и это значение используется в дальнейшем как основание системы счисления для выводных чисел. Система счисления для вывод- ных чисел первоначально установлена в десятичную. Команда О заносит значение основания системы счисления для выводных чисел в стек. 2.2.12. Выходной формат и выходная система счисления Входная и выходная системы счислений влияют только на интерпретацию чисел при вводе и выводе, но не влияют на арифметические вычисления. Большие числа выводятся по 70 цифр на строке. Если строка имеет продолжение, то на это указывает знак \ (обратная косая черта) в конце строки. Можно работать с любыми системами счисления, хотя не все достаточно целесообразны. В частности, например, полезна система счисления с основанием 1000, при которой выводимые числа печатаются группами по три цифры. Восьмеричная и шестнадцатиричная системы счисления используются для пере- вода в и из этих систем счисления. 2.2.13. Внутренние регистры Числа или цепочки могут быть запомнены во внутренних регистрах или загружены в стек из регистров, используя команды s и l. По команде sx происходит извлечение зачения верхушки стека и запоминание его в регистре x. x может быть любым символом. По команде lx происходит запись значения регистра x в верхушку стека. Команда l не изменяет содержи- мое регистра, а команда s его изменяет. 2.2.14. Стековые команды Команда c чистит стек. Команда d дублирует число в вер- хушке стека. Команда z заносит в стек длину стека. Команда X заменяет число в верхушке стека его точностью. Команда Z заменяет верхушку стека его длиной. - 27 - 2.2.15. Описания и вызовы функций Строка из символов в коде КОИ-8, заключенная в квадрат- ные скобки, заносится в стек. Команда q прекращает работу или, при выполнении по строке, уменьшает уровень вложенности на два. 2.2.16. Внутренние регистры - программирование на dc Для того, чтобы программировать, работая с программой dc, можно пользоваться командами загрузки и запоминания l и s, запоминания строк "[]", командой выполнения x, командами проверки <&lt;, >&gt;, =, !<&lt;, !>&gt;, != Команда x рассматривает вер- хушку стека как команду программы dc и выполняет ее. Команды проверки сравнивают два верхних элемента стека, и, если условие справедливо, то выполняется регистр x, который следует за операцией отношения. Например, для того, чтобы напечатать числа 0-9, надо набрать следующую программу: [lip1+ si li10>&gt;a]sa 0si lax 2.2.17. Стековые регистры и массивы Следующие команды были разработаны для использования не людьми, а компилятором. Они охватывают стековые регистры и массивы. Кроме стека, с которым работают команды, dc имеет также несколько индивидуальных стеков для каждого регистра. Эти регистры оперируют с командами S и L. Sx заносит верхнее значение главного стека в стек для регистра x. Lx извлекает значение из стека регистра x и заносит результат в основной стек. Команды s и l также работают с регистрами, но не как со стеками. l не изменяет верхушку регистрового стека, а s разрушает то, что там находилось ранее. К командам для работы с массивами относятся : и ;. :x извлекает значение стека и использует его как индекс к мас- сиву x. Следующий элемент стека запоминается в элементе мас- сива x с этим индексом. Индекс должен быть больше нуля и меньше 2047. ; - это команда для загрузки основного стека из массива x. Значение верхушки стека - это индекс в массиве x, откуда должна произойти загрузка. 2.2.18. Прочие команды Команда ! интерпртирует остаток строки как команду ДЕМОС и передает ее системе для выполнения. Другая команда компилятора - Q. Эта команда использует верхушку стека как число уровней рекурсии, которое надо пропустить. - 28 - 2.3. Выбор решений Основной причиной использования распределителя динами- ческой памяти было то, что программа общего назначения могла быть (и была на самом деле) использована для множества дру- гих задач. Если заранее не известно, какова будет длина цепочки, распределитель принимает значение для ввода и ком- пиляции (т.е. команды, заключенные в квадратные скобки [...]). Результат был таков, что при скромной стоимости во время выполнения все соображения по поводу распределения цепочек и размеров цепочек были удалены из оставшейся части программы, и отладка стала более легкой. Используемый метод тратил примерно 25% доступной памяти. Выбор числа 100 как основания системы счсления для внутренней арифметики по-видимому не имеет явного преиму- щества. Кроме того, основание системы счисления не должно превышать 127 из-за аппаратных ограничений; и при стоимости 5% памяти отладка стала много легче, а десятичный вывод существенно быстрее. Причина создания арифметики стекового типа - дать воз- можность всем командам dc от сложения до выполнения подпрог- рамм по-существу выполняться одинаково. Результатом явилось значительноя степень логического разделения конечной прог- раммы на модули с очень маленькой связью между ними. Из-за недостатка взаимодействия между шкалой и основа- ниями систем счисления разумным было обеспечить понимаемость способа выполнения после изменения шкалы или основания, когда числа уже были введены. Ранняя версия, которая имела глбальные понятия шкалы и основания системы счисления, не была хорошо разработана. Если значение scale интерпретирова- лось в текущей вводной или выводной системе счисления, то изменение системы счисления или шкалы в середине вычисления мог вызвать неправильную интерпретацию результатов. Текущая схема имеет то преимущество, что значение входного и выход- ного оснований систем счисления используется только для вводы и вывода соответственно, и игнорируется во всех других действиях. Значение шкалы не используется для любых сущест- венных целей в любой части программы, а используется только для того, чтобы предотвратить увеличение количества десятич- ных знаков за границы текущей точности. Разумным решением выбора шкалы результатов арифметичес- ких действий было бы то, что при явном указании пользователя ни одна значащая цифра не должна быть отброшена. Действи- тельно, если пользователь хочет сложить числа 2.5 и 3.1415, то кажется разумным дать ему результат 5.6415, поскольку в остальных значащих цифрах нет необходимости. С другой стороны, при умножении и возведении в степень вырабатывается результат с количеством цифр большим, чем у - 29 - операндов, и кажется разумным дать как мимнимум количество цифр в операндах, а не больше, если только пользователь не укажет явно количество цифр, определив значение scale. Квадратный корень может быть вычислен так же, как и умноже- ние. Вполнение деления дает произвольное количество цифр, и не так просто предположить пожелания пользователя относи- тельно количества цифр. В этом случае пользователь должен определить значение scale. Шкала остатка выбрана для того, чтобы можно было восстановить делимое из частного и остатка. Это легко выполнить: ни одна цифра не отбрасывалась. - 30 - СОДЕРЖАНИЕ АННОТАЦИЯ ......................................... 2 1. ВВЕДЕНИЕ .......................................... 2 2. ИНТЕРАКТИВНЫЙ КАЛЬКУЛЯТОР bc ...................... 3 2.1. Простые действия с целыми числами ............... 3 2.2. Основания систем счисления ...................... 4 2.3. Масштабирование ................................. 6 2.4. Функции ......................................... 7 2.5. Индексированные переменные ...................... 8 2.6. Управляющие операторы ........................... 9 2.7. Некоторые детали ................................ 11 2.8. Три важные вещи ................................. 12 2.9. Детальное описание .............................. 13 2.9.1. Обозначения ................................... 13 2.9.2. Знаки ......................................... 13 2.9.2.1. Комментарии ................................. 13 2.9.2.2. Идентификаторы .............................. 13 2.9.2.3. Ключевые слова .............................. 13 2.9.2.4. Константы ................................... 14 2.9.3. Выражения ..................................... 14 2.9.3.1. Простые выражения ........................... 14 2.9.3.1.1. Именованные выражения ..................... 14 2.9.3.1.2. Вызовы функций ............................ 14 2.9.3.1.3. Константы ................................. 15 2.9.3.1.4. Круглые скобки ............................ 15 2.9.3.2. Унарные операции ............................ 15 2.9.3.3. Операция возведения в степень ............... 16 2.9.3.4. Операции группы умножения ................... 16 2.9.3.5. Операции группы сложения .................... 16 2.9.3.6. Операторы присваивания ...................... 17 2.9.4. Отношения ..................................... 17 2.9.5. Классы памяти ................................. 17 2.9.6. Операторы ..................................... 18 2. ИНТЕРАКТИВНЫЙ СТЕКОВЫЙ КАЛЬКУЛЯТОР dc ............. 20 2.1. Описание синтаксиса ............................. 20 2.2. Детальное описание .............................. 22 2.2.1. Внутреннее представление чисел ................ 22 2.2.2. Распределитель памяти ......................... 23 2.2.3. Внутренняя арифметика ......................... 24 2.2.4. Сложение и вычитание .......................... 25 2.2.5. Умножение ..................................... 25 2.2.6. Деление ....................................... 25 2.2.7. Нахождение остатка ............................ 26 2.2.8. Вычисление квадратного корня .................. 26 2.2.9. Возведение в степень .......................... 26 2.2.10. Перевод вводных чисел и входная система счисле- ния ........................................... 26 - 31 - 2.2.11. Выводные команды .............................. 27 2.2.12. Выходной формат и выходная система счисления .. 27 2.2.13. Внутренние регистры ........................... 27 2.2.14. Стековые команды .............................. 27 2.2.15. Описания и вызовы функций ..................... 28 2.2.16. Внутренние регистры - программирование на dc .. 28 2.2.17. Стековые регистры и массивы ................... 28 2.2.18. Прочие команды ................................ 28 2.3. Выбор решений ................................... 29 - 32 -

Популярность: 1, Last-modified: Mon, 29 Jun 1998 13:54:30 GmT