Arsen Gonian – Язык программирования Форт (Forth). Решение задач по программированию. Версия 2. (страница 15)
–0.4000000 Ok
Ноль градусов по Цельсию по-прежнему 32 градусов Фаренгейта, единственное отличие – результат вещественное число, а вот при T=-18 остаток уже не отбрасывается, как в первом случае, и ответ получается точный.
Пример 33. Детская задача. Цена 1 кг конфет обозначим через C1, а Y кг соответственно CY, тогда легко вычислить C1=A/X и CY=C1*Y, а дано X кг за A рублей и количество Y кг, цену которого нужно вычислить.
: B33 ( X A Y -> C1 CY ) \ C1=A/X CY=C1*Y
SWAP ROT / \ X A Y -> Y A/X=C1
SWAP OVER * \ Y C1 -> C1 Y*C1= CY
;
3 9 10 B33 \ 3 кг стоит 9 р, т. е. 3р за 1 кг, а 10 кг будут стоить 3*10=30 р
Ok ( 3 30 )
Вы можете самостоятельно потренироваться на современных ценах различных товаров.
А теперь для дробных цен.
: B33 ( X A Y -> C1 CY ) \ C1=A/X CY=C1*Y
FSWAP FROT F/ \ X A Y -> Y A/X=C1
FSWAP FOVER F* \ Y C1 -> C1 Y*C1= CY
;
3E 9E 10E B33 F. F.
30.000000 3.0000000 Ok
Проверили на тех же данных. И снова не забываем об обратном порядке при печати со стека, не важно с какого (целочисленного или вещественного). Чтобы в начале вывести цену за 1 кг, можно использовать слово FSWAP перед «F.» или переписать строчку
FSWAP FOVER F* \ Y C1 -> C1 Y*C1= CY
таким образом
FDUP F. F* \ Y C1 -> Y*C1= CY
Но в этом случае код не универсален, а значит менее предпочтителен. Желательно вычисление и печать разграничить, чтобы можно было, написанную функцию использовать в различных местах и ситуациях, а не «изобретать велосипед» каждый раз.
Пример 34. Продолжение детских задачек.
: B34 ( X A Y B -> CX CY CX/CY ) \ CX=A/X CY=B/Y CX/CY
SWAP / \ X A Y B -> X A B/Y=CY
SWAP ROT / \ X A CY -> CY A/X=CX
SWAP 2DUP / \ CY CX -> CX CY CX/CY
;
5 30 5 15 B34
Ok ( 6 3 2 )
Цена шоколадных конфет равна 30/5= 6 р/кг, ирисок 15/5=3 р/кг, и соответственно шоколадные конфеты дороже ирисок в 6/3=2 раза. Перепишем для вещественных аргументов, чтобы не терять точность для «неудобных данных».
: B34 ( X A Y B -> CX CY CX/CY ) \ CX=A/X CY=B/Y CX/CY
FSWAP F/ \ X A Y B -> X A B/Y=CY
FSWAP FROT F/ \ X A CY -> CY A/X=CX
FSWAP FOVER FOVER F/ \ CY CX -> CX CY CX/CY
;
5E 30E 5E 15E B34 F. F. F.
2.0000000 3.0000000 6.0000000 Ok
И снова обратный порядок, результат идентичен первому варианту с целыми аргументами.
Пример 35. Детская задачка на движение лодки в стоячей и движущейся воде.
VARIABLE T2
: B35 ( V U T1 T2 -> S ) \ S=S1+S2, S1=V*T1, S2=(V-U)*T2
T2 ! \ V U T1 T2 -> V U T1
ROT DUP ROT * \ V U T1 -> U V V*T1=S1
SWAP ROT – \ U V S1 -> S1 V-U
T2 @ * \ S1 V-U -> S1 [V-U]*T2=S2
+ \ S=S1+S1
;
Манипуляции на стеке неоправданно усложняются с четырьмя и более элементами, поэтому мы сохраним значение T2 в одноименной переменной. Сперва мы вычисляем путь S1 в стоячей воде, затем считывая время T2 из переменной – путь S2 и соответственно ему скорость. Ответ есть сумма двух путей. Проверим написанное слово.
10 5 1 1 B35
Ok ( 15 )
1 час в стоячей воде со скоростью 10 – это путь равный 10*1=10 и такое же время со скоростью 10-5=5. В итоге общий путь 10+5=15.
С вещественными данными слово будет иметь вид:
FVARIABLE FT2
: B35 ( V U T1 T2 -> S ) \ S=S1+S2, S1=V*T1, S2=(V-U)*T2
FT2 F! \ V U T1 T2 -> V U T1
FROT FDUP FROT F* \ V U T1 -> U V V*T1=S1
FSWAP FROT F- \ U V S1 -> S1 V-U
FT2 F@ F* \ S1 V-U -> S1 [V-U]*T2=S2
F+ \ S=S1+S1
;