以下代码是教授在我的计划课程简介中给出的答案,但它出现了错误。看不出原因。
#!r5rs
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
(complex-sqrt 7)
;; ERROR mcar: contract violation
;; expected: mpair?
;; given: 7
在DrRacket中运行时,我使用trace illustartion获取了screenshot错误。
答案 0 :(得分:0)
此处您的代码已转录。请考虑将来发布实际代码而不是屏幕截图。
(define (make-complex a b) (cons a b))
(define (real x) (car x))
(define (imag x) (cdr x))
(define (complex-sqrt x)
(define (sgn v)
(cond ((< v 0) -1)
((= v 0) 0)
(else 1)))
(let ((root (sqrt (+ (* (real x) (real x))
(* (imag x) (imag x))))))
(make-complex (sqrt (/ (+ (real x) root) 2))
(* (sgn (imag x))
(sqrt (/ (- root (real x)) 2))))))
你的教授也提供了(complex-sqrt 7)
部分吗?我们试图得到一个复数的平方根,所以我们应该传递一个复数:
(complex-sqrt (make-complex 5 2))
'(2.27872385417085 . 0.43884211690225433)
根据https://www.wolframalpha.com/input/?i=sqrt(2i%2B5)的说法是正确的!
答案 1 :(得分:0)
complex-sqrt
的实施是不安全的。这意味着它假设你传递一个复数,在这种情况下是用make-complex
创建的。
要解决此问题,您需要检查参数是否复杂:
;; Not 100%. Should use `struct` to not
;; mix with random pairs that happens to have numeric parts
(define (complex? x)
(and (pair? x)
(number? (car x))
(number? (cdr x))))
;; The original code is renamed to unsafe-complex-sqrt
(define (complex-sqrt x)
(if (complex? x)
(unsafe-complex-sqrt x)
(raise-argument-error 'complex-sqrt "complex?" x)))
现在你可以测试一下:
(complex-sqrt (make-complex 7 0))
; ==> (2.6457513110645907 . 0)
(complex-sqrt 7)
; ERROR complex-sqrt: contract violation
; expected: complex?
; given: 7
完美。现在它说你有mot将所需的复数传递给一个需要复杂数字才能工作的函数。
那么原始代码中发生了什么?
在unsafe-complex-sqrt
car
中cdr
使用x
和#t
这些安全操作,如果(pair? x)
提供的参数mcons
不是#!r5rs
,则表示违反合同。
Racket在其<input mdInput placeholder="Name" #filterName name="filterName" >
@ViewChild() input: ElementRef
public clear() {
this.input.NativeElement.value = '';
}
实现中使用markAsPristine()
,因此错误是指R5RS中以m为前缀的每对/列表函数,因为错误没有注意重命名。