Страницы

Превращение F

Убого:

MODULE Power;

 PROCEDURE Do*(x: REAL; n: INTEGER): REAL;
 VAR y: REAL; i: INTEGER;
 BEGIN
  ASSERT(n >= 0);

  y := 1.0; i := n;
  WHILE i > 0 DO
    IF ODD(i) THEN y := y*x END;
    x := x*x; i := i DIV 2
  END
 RETURN
  y
 END Do;

END Power.
Уже лучше:
: power ( real x  integer n -- real )
  real y  integer i

  n 0 < assert
  1.0 =:y
  n =:i
  begin
    i 0 >
  while
    i odd if y x * =:y then
    x x * =:x
    i 2 div =:i
  end
  y
;
Божественно:
: power ( n -- ) ( F: x -- y )
  dup 0< if drop fdrop abort then
  >r 1e
  begin r@ 0> while
    r@ 1 and 0<> if fover f* then
    fswap fdup f* fswap
    r> 2/ >r
  repeat
  r> drop fnip
;

Превращение L

Убого:

MODULE Power;

 PROCEDURE Do*(x: REAL; n: INTEGER): REAL;
 VAR y: REAL; i: INTEGER;
 BEGIN
  ASSERT(n >= 0);

  y := 1.0; i := n;
  WHILE i > 0 DO
    IF ODD(i) THEN y := y*x END;
    x := x*x; i := i DIV 2
  END
 RETURN
  y
 END Do;

END Power.
Уже лучше:
(module Power
  (procedure Do ((x REAL) (n INTEGER)) REAL
  (var ((y REAL) (i INTEGER)))
  (
    (assert (>= n 0))
    (:= y 1.0)
    (:= i n)
    (while (> i 0) (
      (if (odd i)
          (:= y (* y x))
      )
      (:= x (* x x))
      (:= i (div i 2))
    ))
    (return y)
  ))
)
Божественно:
(define (power x n)
(begin
  (when (< n 0) (error "Negative exponent"))
  (let ((y 1.0)
        (i n))
    (let loop ((x x) (i n) (y 1.0))
      (if (> i 0)
          (let* ((y (if (odd? i) (* y x) y))
                 (x (* x x))
                 (i (quotient i 2)))
            (loop x i y))
          y)))))