Конечно, рассматривая арифметику с плавающей точкой, нельзя не затронуть вопрос о преобразованиях данных из символьной формы в форму с плавающей точкой и обратно, осуществляющихся соответственно при вводе и при выводе информации. В процессе работы мы познакомимся с дополнительными видами услуг, предоставляемых системой на этапе преобразования данных, заключающихся в более полном использовании возможностей команд PACK и CVB.
При проведении различного рода преобразований, связанных с представлением числовой информации в виде с плавающей точкой, целые и дробные части чисел рассматриваются отдельно. Существуют программы, способные производить преобразования чисел типа —198.263 из символьной формы в числа с плавающей точкой любого заданного формата. Целая часть, а именно —198., и дробная, т. е. .263, на этапе выполнения преобразований рассматриваются отдельно. Обратный процесс также требует отдельного рассмотрения целых и дробных частей чисел для правильного определения места десятичной точки.
Символьная форма - числа с плавающей точкой
В данном случае нас интересуют только последние этапы преобразования. То есть, иначе говоря, мы предполагаем, что начальные этапы уже выполнены и подпрограмме передаются двоичные эквиваленты целой и дробной части числа, считанного с карты, имеющие вид полных слов. Наша задача состоит в составлении подпрограммы, имеющей на входе два целых числа, представляющих собой соответственно целую и дробную часть, и получающей в результате необходимое число в форме с плавающей точкой.
Конечно, мы должны сделать некоторые предположения относительно формата исходных чисел. Пусть все преобразуемые числа имеют не более семи знаков после точки. Основная программа, занимающаяся преобразованием целой и дробной частей числа в двоичную форму и производящая вызов составляемой нами подпрограммы, считает дробную часть семиразрядным десятичным числом и в этом предположении переводит его в двоичную форму. Предположим, например, что на входе мы имеем десятичное число
55.1
Подпрограмме, в свою очередь, в качестве входных данных поступают числа
0000003716 (=5510)
и
000F324016 (== 100000010)
Входные данные передаются подпрограмме обычным способом, как параметры, первым параметром при этом считается целая часть.
Мы предполагаем, что знак целой части и есть знак, который должно иметь результирующее число с плавающей точкой. Таким образом, сначала проверяется знак первого параметра и соответствующее значение помещается в знаковый разряд слова, предназначенного для формирования числа с плавающей точкой. Впоследствии мы будем (.-.вязаны лишь с модулем целой части. Считается, что второй параметр, т. е. целое число, соответствующее дробной части числа, является положительным.
Что же дальше делать с целой частью? Нужно взять соответствующее двоичное целое и преобразовать его в форму с плавающей точкой. Этого можно добиться так: нужно взять выровненное по правой границе целое, поместить его в поле мантиссы и установить соответствующее значение характеристики. Наше число, записанное в виде короткой константы, выглядит как
46000037
Порядок равен 4616—4016=6. Таким образом, приведенное выше число эквивалентно 5510:
.00003716 х 166 == 3716 х 16° = 5510
Большая точность может быть достигнута при использовании длинного формата вместо короткого. В таком виде наше целое может быть записано как:
4Е000000 00000037
Это тоже 5510:
.000000 0000003716 X 1614 = 5510
Следующим этапом должна быть нормализация полученного числа. Этого можно добиться, сложив его с истинным нулем. Истинный нуль в данном случае понимается как число с плавающей точкой, имеющее нулевую мантиссу и нулевой порядок (характеристика=401в).
Рис. 19.3. Программа преобразования целого числа из общего регистра 7 в эквивалентное представление в формате с плавающей точкой с размещением результата в регистре 4 с плавающей точкой.
Если предположить, что исходное ненормализованное число находилось в регистрах 4 и 5, то нормализация может быть произведена с помощью команды
AD 4, = D'0.0'
По окончании ее выполнения получится
рег. 4 и 5: 42370000 00000000
На рис. 19.3 приведена часть подпрограммы преобразований, предназначенная для перевода целой части числа в форму с плавающей точкой. Впоследствии, рассмотрев всю подпрограмму целиком (рис. 19.5), мы увидим, что к моменту начала выполнения данного сегмента целая часть была помещена в регистр 7, а дробная — в регистр 8.
Порядок преобразований в основном совпадает с уже описанным. Модуль числа помещается в регистр 5, а его знак заносится в нужный разряд с помощью команды N. Затем константа SKELETON пересылается в регистр 4 и по команде OR к ней приписывается соответствующий знак. К сожалению, команд пересылки информации из регистров общего назначения в регистры с плавающей точкой и обратно не существует. Поэтому нам приходится сначала поместить содержимое регистров общего назначения 4 и 5 в память по адресу FPNUM, и лишь затем произвести загрузку регистров с плавающей точкой 4 и 5. Результат нормализуется, как это уже было показано выше, с помощью команды AD.
Процедура обработки дробной части почти совпадает с уже описанной. Необходимо только разделить дробную часть на 107, поскольку она первоначально представлена в виде целого. Соответствующий сегмент программы изображен на рис. 19.4. После выполнения команды OR в общие регистры 7 и 8 попадает умноженная на 107 ненормализованная дробная часть с соответствующим знаком/ Затем результат делится на 10’ и помещается на регистры с плавающей точкой 0 и 1.
Рис. 19.4. Преобразование семиразрядной дробной части в эквивалентное представление в формате с плавающей точкой. Этот фрагмент должен следовать за фрагментом, представленным на рис. 19.3.
Рис. 19.5. Подпрограмма преобразования двоичных целых, представляющих целую и дробную части числа, в формат с плавающей точкой.
Полностью подпрограмма приведена на рис. 19.5. Первая ее часть получает значения параметров и засылает их в регистры 7 и 8. После преобразования каждой из частей полученные результаты складываются и окончательный результат возвращается вызывающей программе через регистр с плавающей точкой 0.
Форма с плавающей точкой - символьная форма
Пусть дано число с плавающей точкой, имеющее короткий формат. Теперь перед нами стоит обратная задача: мы должны сначала разбить число на две части, целую и дробную, и выразить их в виде двоичных целых. Затем полученные целые могут быть переведены в десятичную форму, распакованы и, наконец, распечатаны. В качестве разделителя нужно будет использовать десятичную точку. Рассмотрим общую структуру подпрограммы, имеющей в качестве входного параметра число с плавающей точкой и получающей в результате своей работы два полных слова, являющихся двоичным представлением целой и дробной частей исходного числа.
Снова заметим, что характеристика длинной константы, представляющей собой целое число, равна 4Е1в. Возвращаясь к уже знакомому нам числу 55.1, мы видим, что необходимо, имея его представление в форме с плавающей точкой
42371999 получить целую часть в виде
4Е000000 00000037
Вторая половина второго слова представляет собой искомое значение целой части.
На рис. 19.6 приведена программа, выполняющая необходимые преобразования. По команде LD в регистр с плавающей точкой 5 засылается 0. Для обеспечения возможности продолжения выполнения обработки исходного числа после получения аналога его дробной части, само число помещается в регистр 6. Поскольку подпрограмма должна осуществлять перевод как положительных, так и отрицательных чисел, абсолютная величина исходного числа помещается в регистр 4. При выполнении команды AW на этапе предварительной нормализации вся дробная часть выдвигается вправо за пределы разрядной сетки регистра 5.
Рис. 19.6. Выборка целой части числа с плавающей точкой, адрес которого находится в регистре 3. Результат помещается в регистр 5.
Рис. 19.7. Выборка дробной части числа с плавающей точкой и помещение ее в регистр 6. Этот фрагмент должен следовать за фрагментом, представленным на рис.19.6.
Сложение с нулем не меняет числа, нормализация результата не производится. Итак, вычисления происходят следующим образом:
рег. 4 и 5: 42371999 00000000
+4 Е000000 00000000
Предварительная нормализация дает рег. 4 и 5:
Итак, мы получили требующийся результат. Затем содержимое регистра 5 мы помещаем в общий регистр 5, заменяя его на его дополнение, если число отрицательно.
Поскольку мы уже получили выражение для целой части числа, вычислить дробную очень просто. Для этого достаточно вычесть целую часть из исходного числа. В нашем случае вычитание даст
55.1—55.0=. 1
Если подпрограмма печати предназначена для выдачи результата с семью цифрами после точки, то дробная часть умножается на 107, а далее используется уже известный нам способ получения искомого значения во второй половине длинного регистра с плавающей точкой. Этот способ состоит в выполнении команды AW. Рис. 19.7 иллюстрирует сказанное.
Полная подпрограмма, предназначенная для выполнения рассматриваемых преобразований, приведена на рис. 19.8.
Рис. 19.8. Подпрограмма выборки целой и дробной частей числа с плавающей точкой и их представления в формате целых чисел длиной в полное слово.