Начальный курс программирования на языке Форт

ОПЕРАЦИИ НАД ДРОБНЫМИ ЧИСЛАМИ


Как вы видели, для масштабирования нецелые величины можно выразить в виде пары целых чисел. В некоторых программах вещественные числа могут понадобиться не только для маштабирования. Например, как сложить две дроби, не используя представление с плавающей точкой?

7 . 23 Ж"Н9 =

На Форте вы можете сделать это с помощью команд так называемой дробной арифметики, реализующих операции над числами с фиксированной точкой.

При использовании дробной арифметики мы применяем масштабирование с подразумеваемым положением десятичной точки. Но вместо масштабирования посредством умножения на степень 10 (как принято при вычислениях вручную) мы будем масштабировать путем умножения на степень 2 (как принято при вычислении на компьютере). Таким образом, выражение «десятичная точка» уместно заменить выражением «двоичная точка»"

1 Для истинных математиков Ниже приводится небольшая таблица вещественной аппроксимации различных констант:

2 Для начинающих Этот вопрос подробнее рассматривается в гл 7

Допустим, вы ввели следующее определение: : +1 ( -- масштабная-единица ) 16364 ;

Здесь выбран масштаб» при котором число 16384 представляет положительную единицу (константы будут введены в гл. 8). В двоичной системе счисления число 16384 выглядит следующим образом: 0100000000000000

т. е. это единица в соответствующем масштабе с подразумевае-мой двоичной точкой.

Теперь добавьте к Форту две новые арифметические операции: дробное умножение и дробное деление, выполняемые с учетом выбранного нами масштаба. : *. ( n n -- n) +1 */ ;

: /. ( n n -- n) +1 SWAP */ ;

Что же у вас получилось? При делении единицы на единицу должна получиться единица.1 1 /. . 16384 ok



(Напомним, что в выбранном масштабе 16384 это единица.) Теперь разделите 1 на 2: 1 2 /. . 8192 ok

Здесь 8192 представляет половину единицы (половина от 16384). Следовательно, вы можете решить поставленную задачу таким образом: 7 34 /. 23 99 /. +

Обратите внимание на последнюю операцию.
Для сложения двух дробей мы применяем хорошо знакомый вам знак + Конечно, пока это не совсем удобно, так как вы еще не умеете получать ответы в прежней форме. Для того чтобы представить результат снова в десятичной системе, необходимо ввести 10000 *. . 4381 ok

Ответ составит 4381/10000, или в более привычном виде 0.4381.

С помощью дробной арифметики, используя быстрые операции над целыми числами, вы можете складывать, вычитать, умножать

и делить даже вещественные числа. В вычислительных задачах (в которых выполняется множество арифметических действий), скорость вычислений считается самым важным параметром Перевод же чисел в удобочитаемый вид (в десятичную систему) не столь существен, поскольку выводить нужно лишь конечный результат. Более того, в таких приложениях, как графика и робототехника, вообще не требуется перевод результата в десятичную систему - получаемая информация должна быть понятна , графическому устройству, плоттеру, руке робота или чему-то еще

Имеет смысл решать на компьютере задачи теми средствами, к которым он приспособлен, а не навязывать ему образ действий, являющийся следствием нашего школьного образования

Нам все-таки хотелось бы вводить и выводить дроби с помощью привычных обозначений. Вы были бы не против, если бы Форт-система выводила результат с десятичной точкой в соответствующем месте? А для этого нужно всего лишь одно слово, лред-ставляющее число в традиционном формате. Воспользуемся средствами, описанными в гл. 71:: #.#### DUP ABS 0 <# # # # # 46 HOLD # ROT SIGH #> TYPE SPACE ; : .F ( дробь -- ) 10000 *. #.#### ;

Теперь наше выражение будет иметь вид 7 34 /. 23 99 /. + .F 0.4381 ok

Это не представление с плавающей точкой, но результат в принципе такой же и получен гораздо быстрее.

Допустим, вы хотите, чтобы вводимые аргументы выглядели как вещественные числа, например: .1250 + .3750 = ?

Для того чтобы выполнить такую операцию на Форте, в первую очередь вам потребуется слово, преобразующее числа с десятичной точкой в масштабированную дробь.


Детали мы объясним вам в гл. 7, а для своих текущих потребностей вы можете определить, например, слово : D>F ( d -- дробь) DROP 10000 /. ;

(D>F означает перевод из числа двойной длины в дробное. DOUBLE - двойной, FRACTION - дробь). Теперь можно вводить следующие выражения:.1250 D>F .3750 D>F + .F 0.5000 ok

1 Для пользователей фиг-Форта, систем полиФорт, созданных бо введения Стандарта-83 и других старых систем Перед SIGN слово ROT должно быть опущено

Обратите внимание на то, что необходимо дополнять исходные данные до четырех десятичных знаков.

Вы можете выполнять умножение двух дробей посредством *..7500 D>F .5000 D>F *. .F .3750 ok

Интересно отметить, что если вы выполняете операцию умножения *. дроби на целое, то результат будет целым, например:28 .5000 D>F *. . 14 ok

Применяя операцию /., можно разделить, скажем, -0.3 на 0.95:-.3000 D>F .9500 D>F /. .F -0.3160 ok

Выполняя ту же операцию над двумя целыми, вы получите дробный результат:22 44 /. .F .5000 ok

Если же вы делите посредством /. целое на дробь, то в результате получите целое. Обозначив символом f дробь, а символом i целое, мы можем построить следующую таблицу выполнения операций:ОПЕРАЦИЯ РЕЗУЛЬТАТ f f + f f f - f f i * f i f * f f i / f f f *. f f i *. i i f *. i f f /. f i i /. i i f /. i

Использование двоично-ориентированного масштаба, например числа 16384, а не десятично-ориентированного, например 10000, позволяет обеспечить в пределах 16 разрядов большую точность (точность повышается в отношении 16 к 10). При этом операции */ и /. кодируются на ассемблере чрезвычайно эффективно. Но и число 16384 мы выбрали в качестве единицы произвольно. Если бы было выбрано число 256, то получилось бы восемь разрядов (включая знак) слева от двоичной точки и восемь разрядов справа. Этот метод при необходимости можно применить и к 32-разрядным числам.

Операции *. и /. можно выполнять над тригонометрическими функциями, поскольку значение угла представляется как функция длины окружности, выраженная дробью (в интервале от 0 до 1).Перевод радиан в градусы и обратное преобразование осуществляются весьма просто.


Содержание раздела