Arsen Gonian – Язык программирования Форт (Forth). Решение задач по программированию. Версия 2. (страница 16)
10E 5E 1E 1E B35 F.
15.000000 Ok
На предыдущих данных, как и положено, дает тот же результат, но с типом float.
Пример 36. Без комментариев, сразу приведем решение.
: B36 ( V1 V2 S0 T -> S ) \ S=S0+(V1+V2)*T
2SWAP + * + \ V1 V2 S0 T -> S0+T*(V1+V2)
;
3 5 100 2 B36
Ok ( 116 )
\ 3+5=8, 8*2=16, 16+100=116.
FVARIABLE FS0
: B36 ( V1 V2 S0 T -> S ) \ S=S0+(V1+V2)*T
FSWAP FS0 F! \ V1 V2 S0 T -> V1 V2 T
FROT FROT F+ F* \ V1 V2 T -> T*(V1+V2)
FS0 F@ F+ \ T*(V1+V2)+S0
;
3E 5E 100E 2E B36 F.
116.00000 Ok
По предыдущему опыту мы вводим новую переменную, чтобы уменьшить количество элементов на вещественном стеке. Ответ совпадает с первым вариантом, только вещественного формата, что подтверждает корректность работы написанного слова.
Пример 37. Абсолютно аналогичен предыдущему примеру, за исключением, двух моментов – сумма заменяется разностью, и разность помещается в модуль.
: B37 ( V1 V2 S0 T -> S ) \ S=|S0-T*(V1+V2)|
2SWAP + * – ABS \ V1 V2 S0 T -> |S0-T*(V1+V2)|
;
3 5 100 2 B37
Ok ( 84 )
\ 3+5=8, 8*2=16, |100-16|=84. Проверим как работает модуль, для этого положим S0=10.
3 5 10 2 B37
Ok ( 6 )
\ 3+5=8, 8*2=16, |10-16|=6. Все верно, код работает корректно.
FVARIABLE FS0
: B37 ( V1 V2 S0 T -> S ) \ S=|T*(V1+V2)-S0|
FSWAP FS0 F! \ V1 V2 S0 T -> V1 V2 T
FROT FROT F+ F* \ V1 V2 T -> T*(V1+V2)
FS0 F@ F- FABS \ T*(V1+V2) –> |T*(V1+V2)-S0|
;
3E 5E 100E 2E B37 F.
84.000000 Ok
3E 5E 10E 2E B37 F.
6.0000000 Ok
рис 58
Для вещественного аргумента мы получили тот же ответы в соответствующем формате.
Пример 38. Тривиальная школьная задача, которую мы решим сразу в вещественной форме. При необходимости, желающие смогут самостоятельно написать код для целого аргумента.
: B38 ( A B -> X ) \ X=-B/A
–1E F* FSWAP F/ \ A B -> -B/A
;
10E 3E B38 F.
–0.3000000 Ok
Код «-1E F*» можно заменить на «FNEGATE», который лучше, но для начала может быть менее наглядным.
: B38 ( A B -> X ) \ X=-B/A
FNEGATE FSWAP F/ ; \ A B -> -B/A
Пример 39. Решение квадратного уравнения. Обратите внимание, что в названии вещественной переменной A опущен префиксы «F», так как в этом слове используется одна переменная одного типа применено такое упрощение. Если вас это пугает, то вы легко можете добавить его. Если все слова книги вы добавляете в один файл, то эта проблема будет актуальной, так же вы можете в названиях слов добавлять суффикс I (Integer), для функций с целочисленными аргументами и F, для вещественных, иначе SP-Forth, будет выводить сообщения «B39 isn't unique ()», что не является ошибкой, но предупреждением, о том, что при вызове слова будет вызвано определенное последней слово. Могут возникнуть скрытые ошибки логики работы. Так если вы определили целочисленное слово, затем вещественное и после вызываете попеременно слова с разными аргументами, то как было сказано выше – будет вызвана исключительно последняя реализация, что неизбежно приведет к ошибке, связанное с тем что слова будут работать с аргументами в разных стеках, в итоге, будет либо нехватка аргументов, либо порча других данных не предназначенных для вашего слова. Изменив названия при помощи суффиксов, вы избавитесь от этих проблем.
FVARIABLE A
: B39 ( A B C -> X1 X2) \ X1,X2=(-B+-SQRT(D))/2*A
FROT FDUP A F! F* \ A B C -> B C*A
FOVER FDUP F* \ B C*A -> B C*A B^2
FSWAP 4E F* F- FSQRT \ B C*A B^2 -> B SQRT{B^2-4*C*A=D}
FSWAP -1E F* FSWAP \ B D^0.5 -> -B D^0.5
FOVER FOVER F+ A F@ \ -B D^0.5 -> -B D^0.5 –B+D^0.5 A
2E F* F/ \ -B D^0.5 –B+D^0.5 A -> -B D^0.5 [–B+D^0.5]/[A*2]=X1
FROT FROT F- A F@ \ -B D^0.5 X1 -> X1 –B-D^0.5 A
2E F* F/ \ X1 –B-D^0.5 A -> X1 [–B-D^0.5]/[A*2]=X2
FOVER FOVER F< \ X1 X2 –> X1 X2 X1<X2?