Џрограммы длЯ вычислениЯ с произвольной точностью bc и dc
Џроизводственно-внедренческий кооператив
"€ Ќ ’ … ђ ” … ‰ ‘"
„иалоговаЯ …динаЯ ЊобильнаЯ
ЋперационнаЯ ‘истема
„емос/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
где два выражениЯ свЯзаны одной из шести операций отношениЯ:
<<, >>, <<=, >>=, == или !=. Ћтношение == означает эквива-
лентно, а отношение != означает не эквивалентно. ‡начение
остальных операций отношениЯ Ясно и так.
Ѓудьте внимательны при использовании операций = и ==,
так как некорректное использование одной операции вместо
другой не может быть выЯвлено компилЯтором, а при использо-
вании первой произойдет присваивание, а при использовании
второй - сравнение.
Ћператор 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
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
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
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 -
прописнаЯ буква, то уровень вложенности стека уменьшаетсЯ
на величину верхушки стека.
<<х >>х =х !<<х !>>х !=х
€звлекаютсЯ и сравниваютсЯ два верхних элемента стека.
…сли установленное отношение справедливо, выполнЯетсЯ
регистр х, ‚осклицательный знак означает отрицание.
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, командами
проверки <<, >>, =, !<<, !>>, != Љоманда x рассматривает вер-
хушку стека как команду программы dc и выполнЯет ее.
Љоманды проверки сравнивают два верхних элемента стека, и,
если условие справедливо, то выполнЯетсЯ регистр x, который
следует за операцией отношениЯ. Ќапример, длЯ того, чтобы
напечатать числа 0-9, надо набрать следующую программу:
[lip1+ si li10>>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 -
Last-modified: Mon, 29 Jun 1998 13:54:30 GMT