even?
не похож на if
- вы используете его для проверки, один номер есть.
Он не имеет «ветви»:
> (even? 2)
#t
> (even? 2 "even" "odd")
. . ..\..\Program Files (x86)\Racket\share\pkgs\drracket\drracket\private\rep.rkt:1088:24: even?: arity mismatch;
the expected number of arguments does not match the given number
expected: 1
given: 3
arguments...:
2
"even"
"odd"
Вы можете использовать его в качестве теста на условный:
> (if (even? 2) "even" "odd")
"even"
Если вы хотите проверить несколько условий, это удобно использовать cond
вместо if
:
> (define x 3)
> (cond ((= x 1) "one")
((even? x) "even")
(else "odd"))
"odd"
Но это не повод для DrRacket "замораживания".
Причина этого является то, что разделение не является целочисленным делением, но на самом деле производит точную дробную результат:
> (/ 1 2)
1/2
> (/ (/ 1 2) 2)
1/4
> (/ (/ (/ 1 2) 2) 2)
1/8
так что вы никогда не достигнете случая завершающего.
Вы должны использовать quotient
процедуры:
> (quotient 3 2)
1
> (quotient 2 2)
1
> (quotient 1 2)
0
Воспользовавшись sqr
процедуры и изменив кронштейны от «стиля C» в стиле «схемы», он может выглядеть следующим образом:
(define (powFun base exp)
(if (= exp 0)
1
(if (even? exp)
(sqr (powFun base (quotient exp 2)))
(* (powFun base (- exp 1)) base))))
Или
(define (powFun base exp)
(cond ((= exp 0) 1)
((even? exp) (sqr (powFun base (quotient exp 2))))
(else (* (powFun base (- exp 1)) base))))
> (powFun 2 3)
8
> (powFun 2 0)
1
> (powFun 2 300)
2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376
Примечание стороны: победа взаимодействия dow чрезвычайно полезна для тестирования небольших частей кода, когда вы ищете проблему.