Д. Кнут - Искусство программирования том 2 (3-е издание) - 2001 (Часть 1) (1119452), страница 70
Текст из файла (страница 70)
Не должно быть никаких отступлений от етого принципа, даже в тех случаях, появление которых предельно маловероятно. Надлежащее число значащих цифр следует сохранять в ходе всех промежуточных вычислений, как реализовано в алгоритмах А и М. С. Аппаратная реализация арифметических действий над числами с плавающей точкой. В арсенале почти каждой большой ЭВМ, предназначенной для научных расчетов, содержатся встроенные операции и команды арифметических операций над числамн с плавающей точкой. К несчастью, в аппаратных реализациях таких команд обычно присутствуют некоторые дефекты, приводящие при определенных обстоятельствах к удручающе скверному поведению машины, и, надо надеяться, в будущем создатели вычислительной техники будут уделять больше внимания данному вопросу.
Затраты на зто очень малы, и соображения, представленные в следующем разделе, показывают, какой выигрыш может быль достигнут. Из того, что сегодня известно, следует, что для современных компьютеров не подходят вчерашние компромиссные решения. Компьютер ИХХ, используемый в этой серии книг как пример "типичной" вычислительной машины, оснащается средством расширения для работы с числами в формате с плавающей точкой — арифметическим расширителем. Он доступен за небольшую дополнительную сумму и обеспечивает выполнение слецующих шести команд на аппаратном уровне.
° РАВВ, РЗОВ, РИШ., Рог', Р1.0Т, РСИР (С = 1, 2, 3, 4, 5, 56 оютветственно; Р = 6). Содержимое регистра гА после выполнения команды РАОВ г такое же, как и содер- жимое гА после выполнения команд БТА АСС; 1,ОА 'г'; ЛИР РАОВ. Здесь РАЗΠ— подпрограмма, которая уже появлялась выше в этом разделе, но оба операнда автоматически нормализуются непосредственно перед входом в подпро- грамму, если они еще не были нормэлнзованьь (Если во время предварительной нормализации, но не во время нормализации результата, возникает исчезновение порядка, вызывающая программа о нем ие извещается.) Аналогичные замечания относятся к операциям РЗОВ, РИШ. и Р01Р. Содержимое регистра гА после выпол- нения операции Р1.ОТ совпадает с его же содержимым после выполнения команды БИР РЕОТ в подпрограмме (10). Содержимое гА не искажается командой РСИР г.
Эта команда устанавливает индикатор сравнения в состояние 1.ЕЗБ, ЕООАЕ илн ОЕЕАТЕЕ в зависимости ст того, будет ли содержимое гА "заметно меньше, чем", "примерно равно" или "заметно больше, чем" Ч, как обсуждается в следующем разделе, Ра- бота этой команды в точности моделируется подпрограммой РОИР из упр. 4.2.2 — 17 с ЕРЗ1ЕОИ в ячейке О. Ни одна из команд арифметики с плавающей точкой не воздействует нн на какой другой регистр, помимо гА. Если происходит переполнение илн исчезновение порядка, то включается индикатор переполнения и указывается порядок результа- та по модулю размера байта. Попытка деления на нуль оставляет в регистре гА "мусор" (произвольное значение). Времена выполнения: 4и, 4и, Яи, 11и, Зи и 4и соответственно. е Р1Х (С = 5; Р = 7).
Содержимое гА заменяется целым числом "гоппб(гА)", округленным до ближайшего целого, как на шаге М алгоритма Н. Однако, если этот результат слишком велик и не вмещается в разрядную сетку регистра, устанавлива- ется индикатор переполнения и результат должен трактоваться как неопределенный. Время вьпюлнения: Би, Иногда полезно использовать операторы арифметики с плавающей точкой не. стандартным образом. Например, если бы операция Р1.0Т не была реализована как часть арифметического расширителя компьютера И1Х, можно было бы легко обеспечить ее выполнение для 4-байтовых чисел, написан маленькую подпрограмму РЕОТ БТЗ ЯР Б1.5 1 ЕИТХ 0+4 (12) ЗЕО 1 РАОО 0~ ЯН Л4Р е 1 Эта программа не эквивалентна команде Р1.0Т, так квк в ней предполагается, что 1:1 байт регистра гА равен нулю; кроме того, она портит содержимое регистра гХ. В более общих ситуациях приходится прибегать ко всяким хитростям, потому что переполнение при округлении может происходить даже во время выполнения кома д РЬот.
Аналогично предположим, что й1Х имеет команду Р499, но не имеет РХХ. Чтобы округлить число сч записанное в формате с плавающей точкой, до ближайшего целого числа с фиксированной точкой (причем известно, что число неотрицательно н займет не более трех байтов), в программе можно записать РА00 Р090Е, где в ячейке Р000Е содержится константа результат в гА будет иметь вид (13) В.
История н библиография. Истоки арифметики чисел с плавающей точкой прослеживаются вплоть до вавилонян (около 1800 г. до н. э. или ранее), которые применяли арифметические операции над числами с плавающей точкой по основанию 60, но не имели обозначения для порядка. Нужный порядок всегда некоторым образом "подразумевался" тем, кто производил вычисления. По крайней мере в одном случае обнаружено, что у вавилонян поэучился ошибочный ответ, потому что сложение осуществлялось при неверно выполненном выравнивании операндов, однако это случалось весьма редко (см. О.
ХеокеЬаоег, ТЬе Ехасг Ясюнсеэ ш Апгщшйу (Рг1псегоп, Ь1. 3с Рппсе1оп Пп!гегэ1ьу Ргеээ, 1962), 26-27). Другой пример раннего обращения к формату с плавающей точкой связан с именем греческого математика Аполлония (3 в. до н. з.), который, по-видимому, был первым, кто объяснил, как можно упростить умножение, по крайней мере в простых случаях, собирая степени 10 отдельно от их коэффициентов. Метод Аполлония обсуждается в труде Паина Александрийского "Математическое собрание" (4 в. н. э.). После гибели вавилонской цивилизации представление с плавающей точкой существенным образом использовалось для формирования произведений и частных лишь много веков спустя, когда были открыты логарифмы (1600 г.) и вскоре после этого Отред (ОпЕЬГгед) изобрел логарифмическую линейку (1630 г.). Примерно в тот же период было введено современное обозначение "х" " для порядков; отдельные символы для квадрата х, куба х и т. д.
использовались и раньше. Арифметика с плавающей точкой была включена в конструкцию некоторых из самых ранних вычислительных машин. Это было независимо предложено Леонардо Торресом-и-Овьедо (Ьеопагг(о Тоггеэ у Циегедо) в Мадриде (1914 г.), Конрадом Цузе (Копгаг( Еизе) в Берлине (1936 г.) и Джорджем Стибицем (Сеогбе БВЫСа) в Нью-Джерси (1939 г.), В машине Пузе использовалось двоичное представление с плавающей точкой, которое он назвал полулогарифмической нотацией; он также реализовал соглашение относительно операций с некоторыми особыми величинами, подобными "оо" и "не определено'". Первой американской вычислительной машиной, в которой появились средства для выполнения операций в формате с плавающей точкой, была Модель Ч (Вей ЬаЬогагогии), за которой последовала гарвардская машина Марк П.
Обе эти машины, спроектированные в 1944 году, были репейными вычислительными устройствами. (См, В. Ванде!1, Тйе Ог!8!пз ог П!8!га) Сотригегв (Вег!!и: Брг!пбег, 1973), 100, 155, 163-164, 259-260; Ргос. Бушр. Еагйе-Бса(е Е!!81!а( Са!си!айпй МасЬшегу (Нагтагс), 1947), 41-68, 69 — 79; 0а!ашагюп 13 (Аргй, 1967), 35-44 (Мау, 1967), 45-49; Лей. й!г аляев. МагЬ. илс( РЬувй 1 (1950), 345-346.) Использование двоичных чисел с плавающей точкой серьезно обсуясдалось в 1944 — 1946 годах группой исследователей из Школы Мура (Мооге БсЬоо!) в связи с планами создания первой элекшронной вычислительной машины, но оказвлосяч что на лампах электронную схему, реализующую арифметику с плавающей точкой, выполнить гораздо труднее, чем на реле. Конструкторы первых электронных машин поняли, что масштабирование — зто целая проблема в программировании, но они чувствовали, что это всего лишь небольшая часть общей работы по программированию в те годы.
Конечно„масштабирование в явном виде чисел с фиксированной запятой казалось вполне окупающим затраченные время и усилия, поскольку программист при этом вынужден был все время держать вычисления в поле зрения и заботиться аб их точности. Далее конструкторы возражали, что при представлении чисел с плавающей точкой занимается ценное место в памяти, так как нужно хранить порядки. Кроме того, схемотехнические решения арифметики с плавающей точкой трудно приспособить к вычислениям с многократной точностью.
(См. гоп Непглапп'э Со!!есгеп' 1гогйз 5 (Нею Уогй: Масппйап, 1963), 43, 73-74.) Конечно же, в это время они создавали машину, которая была первой машиной с хранимой в памяти программой и второй электронной машиной, и им предстояло выбрать формат либо с фиксированной, либо с плавающей точкой, но не оба сразу. Они предвосхитили составление программ двоичной арифметики с плавакицей точкой, и команды "сдвиг влево" и "сдвиг вправо" фактически были введены в эти машины, главным образом, с целью повышения их эффективности. Первой машиной, которая имела средства для выполнения арифметических операций с обоими форматами, была, по-видимому, ЭВМ, разработанная фирмой "Дженерал Электрик" (см.
Ргос. 2пг( Бутр, Еагйе-Бса(е Пй(га! Са)си! аапй МасЬшегу (СашЬгк(бе, Маввс Нагтап! Сп!четв!гу Ргезэ, 1951), 65 — 69). Подпрограммы для работы в формате с плавающей точкой, интерпретирующие системы для ранних ЭВМ, были составлены Д. Дж. Уилером (Е!. 3. %Ьее!ег) и другими и впервые опубликованы в книге %!Псез, %Ъее!ег, О!Н, ТЬе Ргерагабоп оу Ргойгашз Гог ал Е!ее!гоп!с О!8йа! Сошрисег (Невйпя, Мазал Адсйвоп-%ев1еу, 1951) (см. подпрограммы А1-А11). Интересно отметить, что в ней описаны программы для десятличноео представления с плавающей точкой, хотя использовалась двоичная ЭВМ; другими словами, числа представлялись в виде 1О'7', а не 2'~, и поэтому для операций сдвига требовались умножения или деления на 10.
На этой машине десятичное масштабирование выполнялось почти так же просто, как сдвиг, а десятичное представление значительно упрощало ввод-вывод. Авторы большинства публикаций при описании деталей реализации подпрограмм арифметики ссылаются на технические отчеты многочисленных производителей компьютеров, но иногда встречаются ссылки на открытые источники. Помимо упомянутых выше работ, определенный исторический интерес представляют следующие: Н.
Н. Б!ай апб Р. В. МасМН1ап, ЛХагЬ, Сошр. 5 (1951), 86-92, в которой описана программа, "прошитая" на специальной сменкой панели; В. МсСгас1сеп, Р?я!га! Сотригег Рго8гатт!пй (5?ен Уог)с: %Иву, 1957), 121-131; 3. %. Сагг П1, САСМ- 2, 5 (Мау, 1959), 10-15; %. С. %абеу, эАСМ Т (1960), 129-139; П. Е. КпцГЬ, эАСМ 8 (1961), 119-128; О. Кезпег, САСМ 5 (1962), 269-271; Р. Р. Вгоо)гз апг! К. Е. 1гегэоп, Аигопгабс Паса Ргосенз!п8 (Хеш Ъог)с: %йеу, 1963), 184-199. Дискуссия относительно арифметики с плавающей точкой с точки зрения разработчиков компьютеров представлена в работах я.