Ваша процедура продолжается вечно, если y отрицателен, вы можете исправить это, изменив if
на cond
, который имеет условие с другим кодом для размещения отрицательного числа, если y действительно отрицательно.
Часть, которая имеет проблему, (if (= y 1) x (+ x (RecursiveMultiply x(- y 1))))
в основном говорит , если y равен 1, вернуть x. Если y не равен 1, повторите процедуру после уменьшения y. Ваша проблема в том, что если y отрицателен или равен нулю, он уже меньше 1. Вычитание 1 из отрицательного числа / нуля только толкает y все дальше и дальше от 1, и вы никогда не достигнете 1. Ваша процедура застревает в бесконечном цикле и вызывает сбой интерпретатора.
Вот как вы решаете проблему:
(define RecursiveMultiply
(lambda(x y)
(cond ((= y 1) x)
((= y 0) 0)
((< y 1) (* -1 (RecursiveMultiply x (- y))))
(else (+ x (RecursiveMultiply x (- y 1)))))))
Я также хотел бы отметить, что ваша процедура медленная, она запускает O (n), что означает, что время / пространство, необходимое для запуска процедуры, растет линейно с ростом входных данных, что очень плохо при работе с большими номера. Я бы рекомендовал сделать это итеративной функцией, чтобы она выполнялась O (log n), намного более быстрой функцией.
Вот пример итеративной процедуры умножения, которую я написал, которая запускает O (n) наихудший случай и O (log n) лучший случай:
(define (mult a b c)
(define (double x)
(* x 2))
(define (halve x)
(/ x 2))
(cond ((= b 0) c)
((even? b)
(mult (double a)(halve b) c))
(else
(mult a (- b 1) (+ c a)))))
(define (two-number-mult x y)
(mult x y 1))
Попробуйте воссоздать это, но с вашей процедурой.