18+
реклама
18+
Бургер менюБургер меню

Arsen Gonian – Язык программирования Форт (Forth). Решение задач по программированию. Версия 2. (страница 6)

18

Протестируем на числах 4 и 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)=(-)

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.

Если вам нужен другой порядок вывода результатов, то самостоятельно решите эту задачу для обоих вариантов, слова ниписаны в соответствии со стековой нотацией.

Полезные слова (если переименовать и разбить некоторые из приведенных выше, то получим список, который можете использовать как свою маленькую математическую библиотеку):

: SquarePerimeter       ( a -> P=4*a ) 4E F* ;

: SquareArea             ( a -> S=a*a ) FDUP F* ;

: RectanglePerimeter       ( a b -> P=2*[a+b] ) F+ 2E F* ;

: RectangleArea             ( a b -> S=a*b ) F* ;

: CircleLength             ( r -> l=2*Pi*r ) 2E FPI F* F* ;

: CircleArea             ( r -> S=Pi*r*r ) FDUP F* FPI F* ;

: CubeVolume                   ( a -> V=a*a*a ) FDUP FDUP F* F* ;

: CubeLateralSurfaceArea       ( a -> S=6*a*a ) FDUP F* 6E F* ;

: RectangularPrismVolume             ( a b c -> V=a*b*c ) F* F* ;

: RectangularPrismLateralSurfaceArea       ( a b c -> S=2*[a*b+b*c+a*c] ) FOVER FOVER F+ FROT FROT F* FSWAP FROT F* F+ 2E F* ;

: ArithmeticMean       ( a b -> [A+B]/2 ) F+ 2E F/ ;

: GeometricMean       ( a b -> SQRT[A*B] ) F* FSQRT ;

Тесты проведите самостоятельно.

рис 21 Результат работы целочисленного и вещественного вариантов примера B10

BEGIN 11-20

Пример 11. Отличается от 10-ого примера незначительными поправками. Просто заменяем квадрат на модуль: код «DUP *» на «ABS» (и «FDUP F*» на «FABS» для вещественных аргументов).

: 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|)=(-)

FROT FROT FOVER FOVER F*       \ (+) |A| |B| (-) -> (+) (-) |A| |B| (|A|*|B|)=(*)

FROT FROT F/             \ (+) (-) |A| |B| (*)-> (+) (-) (*) (|A|/|B|)=(*)

;

Рис 22

В комментариях (скобках) соответствующие сумма, разность, произведение и частное взяты в фигурные скобки для визуального выделения элементов на стеке. Обычные скобки в данном случае применять нельзя, так как они обозначают комментарий и являются зарезервированными словами Форта и системы программирования SP-Forth в частности.

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

Пример 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