High Arsen Gonian Academy
Шрифт:
За грамотные английские названия не ручаюсь.
Пример 10. Вход два числа, не равные нулю. Вычислим сумму, разность, произведение и частное их квадратов, те есть:
: B10 ( A B -> A^2+B^2 A^2-B^2 A^2*B^2 A^2/B^2 )
SWAP DUP * SWAP DUP * \ A B ->A^2 B^2
2DUP + \ A^2 B^2 -> A^2 B^2 (A^2+B^2)
ROT ROT 2DUP – \ A^2 B^2 (A^2+B^2) -> (A^2+B^2) A^2 B^2 (A^2-B^2)
ROT ROT 2DUP * \ (+) A^2 B^2 (-) -> (+) (-) A^2 B^2 (A^2*B^2)
ROT ROT / \ (+) (-) A^2 B^2 (*) -> (+) (-) (*) (A^2/B^2 )
;
Протестируем
4 2 B10
Ok ( 20 12 64 4 )
Всё корректно, проверяйте самостоятельно. В комментариях я сократил сумму, разность и произведение квадратов до соответствующих операций в скобках. Специально подобраны такие числа, чтобы результат деления был целочисленным, но это не обязательно – код для вещественных аргументов избавит нас от таких неудобств:
: B10 ( A B -> A^2+B^2 A^2-B^2 A^2*B^2 A^2/B^2 )
FSWAP FDUP F* \ A B -> B A^2
FSWAP FDUP F* \ B A^2 -> A^2 B^2
FOVER FOVER F+ \ A^2 B^2 -> A^2 B^2 (A^2+B^2)
FROT FROT FOVER FOVER F- \ A^2 B^2 (A^2+B^2) -> (A^2+B^2) A^2 B^2 (A^2-B^2)
FROT FROT FOVER FOVER F* \ (+) A^2 B^2 (-) -> (+) (-) A^2 B^2 (A^2*B^2)
FROT FROT F/ \ (+) (-) A^2 B^2 (*) -> (+) (-) (*) (A^2/B^2)
;
Тест примера 10:
1E-1 2E-1 B10 F. F. F. F.
0.2500000 0.0004000 -0.0300000 0.0500000 Ok
Не забываем, что оператор F. Печатает число с вершины стека, поэтому сначала напечатается частное, затем произведение, после чего разность и в конце сумма.
0,25 = 0,01/0,04; 0,0004 = 0,01*0,04; -0,03 = 0,01-0,04; 0,05 = 0,01+0,04.
Если вам нужен другой порядок вывода результатов, то самостоятельно решите эту задачу.
BEGIN 11-20
Пример 11. Отличается от 10-ого примера незначительными поправками. Просто заменяем квадрат на модуль: код «DUP *» на «ABS».
: B11 ( A B -> {|A|+|B|} {|A|-|B|} {|A|*|B|} {|A|/|B|} )
SWAP ABS SWAP ABS \ A B ->|A| |B|
2DUP + \ |A| |B|-> |A| |B| (|A|+|B|)
ROT ROT 2DUP – \ |A| |B| (|A|+|B|) -> (|A|+|B|) |A| |B| (|A|-|B|)
ROT ROT 2DUP * \ (+) |A| |B| (-) -> (+) (-) |A| |B| (|A|*|B|)
ROT ROT / \ (+) (-) |A| |B| (*)-> (+) (-) (*) (|A|/|B|)
;
В случае для вещественных аргументов:
: B11 ( A B -> {|A|+|B|} {|A|-|B|} {|A|*|B|} {|A|/|B|} )
FSWAP FABS \ A B -> B |A|
FSWAP FABS \ B |A| -> |A| |B|
FOVER FOVER F+ \ |A| |B|-> |A| |B| (|A|+|B|)
FROT FROT FOVER FOVER F- \ |A| |B| (|A|+|B|) -> (|A|+|B|) |A| |B| (|A|-|B|)
FROT FROT FOVER FOVER F* \ (+) |A| |B| (-) -> (+) (-) |A| |B| (|A|*|B|)
FROT FROT F/ \ (+) (-) |A| |B| (*)-> (+) (-) (*) (|A|/|B|)
;
В
Тест на корректность работы написанных слов произведите самостоятельно.
Пример 12. Вычислить гипотенузу и периметр прямоугольного треугольника по его катетам. Так как мы имеем дело с квадратным корнем, сразу приведем код для случая вещественного аргумента.
: B12 ( A B -> C P ) \ C=Квадратный_Корень(A^2+B^2) P=A+B+C
FOVER FDUP F* \ A B -> A B A^2
FOVER FDUP F* \ A B A^2 -> A B A^2 B^2
F+ FSQRT \ A B A^2 B^2 -> A B Квадратный_Корень(A^2+B^2)=C
FROT FROT F+ \ A B C -> C A+B
FOVER F+ \ C A+B -> C A+B+C=P
;
Проверим на прямоугольном треугольнике с катетами 3 и 5:
3E 4E B12 F. F. \ вызываем нашу подпрограмму и печатаем результат
12.000000 5.0000000 Ok
3^2+4^2=25. Квадратный корень из 25=5. 5+3+4=12– что является истиной. В данном случае специально подобрана Пифагорова тройка, для простоты проверки. Проверим общий случай:
3E 5E B12 F. F.
13.830952 5.8309519 Ok
Можете самостоятельно проверить истинность теста.
Пример 13. Найти площади двух кругов (с общим центром) и кольца между ними. Даны радиусы R1 и R2, причем R1 > R2. Как и ранее сперва напишем слово для целочисленных чисел. Если не совсем понятно почему не написать сразу универсальный вариант для вещественных данных, то поясняю: отладка в этом случае наиболее проста для сложных слов и для начинающих программистов, так как все данные на стеке видны сразу после их ввода, то удается проверить и понять работу кода вводя команду за командой. Этого преимущества лишены операторы для работы с вещественными числами. После написания слова с целыми аргументами не сложно перевести его код для работы с вещественными и получить результат того же типа.
: B13 ( R1 R2 -> S1 S2 S3) \ S1=Pi*R1^2 S2= Pi*R2^2 S3=S1-S2
SWAP DUP * 314 * \ R1 R2 -> R2 (Pi*R1^2)=S1
SWAP DUP * 314 * \ R2 S1 -> S1 (Pi*R2^2)=S2
2DUP – \ S1 S2 -> S1 S2 (S1-S2)=S3
;
Запустим наше слово на примере двух кругов с радиусами 25 и 15 соответственно.
25 15 B13
Ok ( 196250 70650 125600 )
Выше приведен вариант кода с целочисленными аргументами, причем все 3 площади больше в 100 раз из-за того, что мы приняли Пи равным 314. Перепишем пример для случая вещественных аргументов.