Как составляется программа работы машины
А. Д. Смирнов
Предположим, что машина установлена в Госбанке, в отделе, где производится обмен валюты. Приехавший в СССР турист из Франции хочет обменять 20 500 франков на рубли.
По курсу того дня 1000 франков равнялись 11 р. 45 коп. Сколько рублей ему нужно уплатить?
Задача сводится к решению простой пропорции
1000 фр. -1145 коп.,
20500 фр. — Х коп.,
откуда
x = 20500 в 1145 / 1000
Как же составить программу, чтобы эту задачу решила машина? Разместим требуемые для решения данные в ячейках оперативного запоминающего устройства:
1000 — в ячейке 10 ,
1145 -в ячейке 4 ,
а сумму меняемых франков, в данном случае 20 500, будем засылать в ячейку 12 .
- Последовательность команд в программе будет такова:
- Послать число из ячейки 11 , т. е. 1145, в сумматор.
Назовем операцию посылки в сумматор “вторым сложением” ( Сл2 ) и в соответствии с этим обозначим
сокращенно эту команду Сл2 11 . - Умножить число в сумматоре, т. е. 1145, на число из ячейки 12 , т. е. на 20 500.
Сокращенно это запишется так: Ум 12 . Произведение получится в сумматоре. - Разделить число в сумматоре на число из ячейки 10 , т. е. на 1000.
Сокращенно: Дл 10. - Получаемое в сумматоре частное отпечатать.
Сокращенно Пч 00.
Перепишем всю программу в сокращенной записи:
Сл2 11
Ум 12
Дл 10
Пч 00
В этой программе все действия, следующие друг за другом, записаны тем же количеством команд. Выполнив эту программу из четырех команд, машина отпечатает ответ 23 473 коп.
Практически, конечно, никто не станет решать подобную задачу на электронной машине. Программы задач, в действительности решаемых на машине, во много раз длиннее, а количество действий, которые должна выполнить машина для решения одной задачи, составляет от сотен тысяч до миллиардов.
Если бы приходилось все до одного действия, необходимые для решения задачи, выписывать в виде последовательности команд, то программа получилась бы очень длинной, и времени на составление программы потребовалось бы примерно столько же, сколько ушло бы на решение этой задачи при помощи клавишной электромеханической машины. Но обычно процесс решения задачи распадается на многократное повторение вычислений по одним и тем же формулам, но с подстановкой в эти формулы каждый раз новых чисел. Поэтому для каждого участка достаточно составить программу одноразового вычисления по формуле и выполнять ее много раз подряд, пока не получим нужный результат. Такой многократно исполняемый участок программы называется циклом , а вся программа оказывается составленной из ряда циклов.
Цикличность участков программы можно легко уяснить на примере извлечения квадратного корня. Извлечем корень из 7,360369 обычным школьным способом, получая цифру за цифрой: sqrt (7,360369) = ?2,713. Hо можно найти значение корня и другим способом.
Зададимся очень грубым значением корня, а затем будем уточнять его по следующей формуле:
Уточненное значение = 1/2 * (предыдущее, менее точное значение + подкоренное выражение / предыдущее, менее точное значение корня)
В нашем случае за грубое значение возьмем приблизительно половину подкоренного выражения, например 3,5, и уточним теперь это значение:
1/2*(3,5 + 7,360368/3,5)=2,80148
Уточним значение корня еще раз опять по этой же формуле, но вместо 3,5 подставим только что найденное более точное значение 2,80148:
1/2*(2,80148 + 7,360368/2,80148)=2,71439
Уточним третий раз:
1/2*(2,71439 + 7,360368/2,71439)=2,71300
Третьего уточнения оказалось достаточно, чтобы получить ответ с пятью верными цифрами после запятой. Если бы потребовалось получить результат с большим числом верных знаков, то трех уточнений могло оказаться недостаточно, пришлось бы сделать еще несколько уточнений. Однако программа для вычисления квадратного корня не будет длиннее оттого, три или десять уточнений потребуется произвести. Убедимся в этом, написав программу вычисления корня квадратного, например для одноадресной машины.
Предварительно занесем число 7,360369, из которого требуется извлечь корень, в ячейку 10 оперативного запоминающего устройства, число 1/2 — в ячейку 11, а уточняемое значение корня (3,5) в ячейки 12 и 13. Операцию занесения числа в сумматор, как и раньше, обозначим (Сл2) и присвоим ей номер 02, операцию сложения числа в сумматоре с числом в ячейке обозначим Сл1 (01), умножение числа в сумматоре на число в ячейке — Ум (06), деление числа в сумматоре на число в ячейке — Дл (07). Результат всегда получается в сумматоре. Если его надо записать в ячейку, эту операцию обозначим Пб (16), т. е. посылка на барабан. Такие шифры операций применяются, например, в универсальной машине “Урал”.
Запишем программу в виде чисел, а рядом будем писать пояснения (смотри таблицу 1, команды 1-6).
Таблица 1.
Номер команды |
Номер ячейки, в которой хранится команда |
Обозначение операции |
Команда | Пояснение | |
шифр операции |
адрес | ||||
1 | 21 | Сл2 | 02 | 10 | Число 7,360369, находящееся в ячейке 10, заносится в сумматор. |
2 | 22 | Дл | 07 | 12 | Число в сумматоре, т. е. 7,360369, делится на число, находящееся в ячейке 12, а там находится число 3,5. Частное, т. е. 2,10296, получается в сумматоре. |
3 | 23 | Сл | 01 | 12 | Число в сумматоре, т. е. 2,10296, складывается с числом, находящимся в ячейке 12, а там по-прежнему находится число 3,5. |
4 | 24 | Ум | 06 | 11 | Число в сумматоре, т. е. 5,60296, умножается на число, на- ходящееся в ячейке 11, т.е. на 1/2; произведение (2,80148), полу- ченное в сумматоре, и есть уточ- ненное значение корня. |
5 | 25 | Пб | 16 | 12 | Посылаем его в ячейку 12. Оно запишется вместо бывшего там ра- нее числа 3,5. |
6 | 26 | Ср | 14 | 13 | Число в сумматоре сравнивается с числом в ячейке 13, если числа не совпадают, выдается сигнал w в УУ. Число в сумматоре при этом изменяется. |
7 | 27 | Е1 | 21 | 21 | Если после выполнения преды- дущей команды в УУ пришел сиг- нал (в из АУ, управление передает- ся команде в ячейке 21; если сиг- нал не пришел, то управление пе- редается следующей по порядку, восьмой, команде, которая нахо- дится в ячейке 28. |
8 | 28 | Сл2 | 02 | 12 | |
9 | 29 | Пч | 32 | 00 | Печать результата |
10 | 30 | Ост | 37 | 00 | Остановка машины |
Для следующего уточнения нам уже не надо составлять программу дальше, достаточно повторить все команды, начиная с первой, еще раз.
Теперь при выполнении второй команды число в сумматоре уже будет делиться не на 3,5, а на 2,80148, так как именно оно находится сейчас в ячейке 12, и т. д. В результате выполнения всех пяти команд в ячейке 12 получится уже следующее уточнение 2,71439.
Для повторения цикла из пяти команд следует применить операцию передачи управления, которая обозначается Е2 (22). Следовательно, шестая команда, помещенная в ячейку 26, будет: 22 21 — двадцать один в адресной части указывает, что передать управление надо снова первой команде (напомним, что команды и числа в машине характеризуются адресом ячейки, в которой они хранятся).
Итак, мы показали, что многократным повторением куска программы из шести команд может быть с любой точностью произведено вычисление квадратного корня.
Но, работая по такой программе, машина никогда не остановится. Сделав одно уточнение, она перейдет к следующему, и т. д. А нам надо проделать лишь столько уточнений, сколько нужно, чтобы получить правильный ответ.
Как же убедиться в том, что нужная точность достигнута? Надо сравнить между собой два результата: предыдущий и уточненный. Если они равны, дальше продолжать уточнения не надо, а нужно отпечатать результат. Дополним эту программу.
Обозначим операцию сравнения Ср (М), операцию условной передачи управления Е1 (21), операцию печати результата Пч (32) (смотри таблицу 1, команды 7-10).
Но чтобы цикл при необходимости повторился правильно, надо в ячейку 13 послать последнее уточненное значение корня, находящееся в ячейке 12 (для чего вначале его придется вызвать в сумматор, а потом послать в ячейку 13). Уточненное значение корня к моменту выполнения команды сравнения уже должно находиться в ячейке 13. Поэтому команды для посылки его туда должны быть выполнены до команды сравнения. Эти команды разместим в начале программы в ячейках 19 и 20. И начинать цикл будем с ячейки 19, т. е. в адресной части команды условного перехода поставим число 19.
Перепишем теперь программу начисто, номера команд значения не имеют, важно лишь, в каких ячейках команды размещены.
Таблица 2.Номер ячейки, где хранится команда |
Содержание ячейки (команда) | ||
Шифр операции | адрес | ||
19 | Сл2 | 02 | 12 |
20 | Пб | 16 | 13 |
21 | Сл2 | 02 | 10 |
22 | Дл | 07 | 12 |
23 | Сл1 | 01 | 12 |
24 | Ум | С6 | 11 |
25 | Пб | 16 | 12 |
26 | Ср | 14 | 13 |
27 | Е1 | 21 | 19 |
28 | Сл2 | 02 | 12 |
29 | Пч. | 32 | 00 |
30 | Ост | 37 | 00 |
Все примененные здесь команды взяты из состава команд машины “Урал”.
Обычный путь программирования выглядит так: составляется схема решения задачи, в которой указывается, какие циклы встречаются и какие переходные команды нужно между ними поставить. Потом составляются программы циклов.
После этого все отдельно составленные программы циклов соединяются переходными командами в одну общую программу. После составления программа выверяется, пробивается на перфокартах или перфоленте и вводится в машину.
Составление программы требует большой внимательности и навыка. Ошибка в одном числе изменит значение команды и сделает программу неверной.
А нельзя ли часть работы программиста переложить на саму машину? Очевидно, можно. Работы по автоматизации программирования ведутся как у нас в Союзе, так и за рубежом, и в этой области получены хорошие результаты. Одним из самых простых методов, но еще не полностью автоматическим является метод библиотечных подпрограмм.
Например, нами составлена уже программа для нахождения корня квадратного. Проверили ее на машине, устранив все случайно сделанные ошибки, и нашли при помощи машины корень из 7,360369. А через некоторое время другому работнику нужно было извлечь корень из 8,056. Нужно ли составлять ему заново программу? Нет, очевидно. Ведь команды в программе будут те же самые, только в ячейку 10, куда раньше посылалось число 7,360369, надо послать 8,056, а в ячейки 12 и 13, где стояло 3,5, послать 4, и программа готова к работе.
Для всех простых задач, например для нахождения тригонометрических функций по значению угла, нахождению логарифма числа и т. п., программы составлены. И если в сложной задаче в каком-нибудь месте потребуется извлечь корень квадратный или вычислить синус угла, то этот кусок программы заново не надо составлять, а в программу нужно вписать команды из ранее составленной программы, изменив только адреса в соответствии с расположением материала в новой программе.
Набор таких программ, называемых стандартными подпрограммами, составит как бы библиотеку программ. Эти подпрограммы набиваются на перфоленте или перфокартах, и там же пробивается еще одна общая для всех программа, которая вводит необходимые для решения данной задачи подпрограммы в ОЗУ. Теперь программисту надо составить только ту часть программы, для которой нет еще стандартных подподграмм, и ввести в машину указания, какие из подпрограмм потребуются при решении данной задачи. Машина по этим указаниям сама выберет из библиотеки эти подпрограммы и свяжет их с основной программой, изменив в них адреса команд. Существуют в еще большей степени автоматизированные программирующие программы. При пользовании ими достаточно ввести в машину формулы, закодированные в цифровой форме. Машина сама составит рабочую программу для вычислений по этим формулам и пробьет эту программу на перфоленте или перфокартах. После этого заготовленная таким образом рабочая программа вводится в машину и по ней выполняются все вычисления.
Глава из книги “Современные математические машины”, М., 1959 г., стр. 78-84.
Перепечатывается с разрешения автора.