Reimplement unboxing of complex division.
Add special cases to be consistent with untyped Racket. Found using random testing.
This commit is contained in:
parent
8c89451fbb
commit
77b89fab99
|
@ -183,8 +183,8 @@
|
||||||
#`(c1.bindings ... c2.bindings ... cs.bindings ... ...
|
#`(c1.bindings ... c2.bindings ... cs.bindings ... ...
|
||||||
;; we want to bind the intermediate results to reuse them
|
;; we want to bind the intermediate results to reuse them
|
||||||
;; the final results are bound to real-binding and imag-binding
|
;; the final results are bound to real-binding and imag-binding
|
||||||
#,@(let loop ([o1 (car (syntax->list #'reals))]
|
#,@(let loop ([a (car (syntax->list #'reals))]
|
||||||
[o2 (car (syntax->list #'imags))]
|
[b (car (syntax->list #'imags))]
|
||||||
[e1 (cdr (syntax->list #'reals))]
|
[e1 (cdr (syntax->list #'reals))]
|
||||||
[e2 (cdr (syntax->list #'imags))]
|
[e2 (cdr (syntax->list #'imags))]
|
||||||
[rs (append (syntax-map (lambda (x) (unboxed-gensym "unboxed-real-"))
|
[rs (append (syntax-map (lambda (x) (unboxed-gensym "unboxed-real-"))
|
||||||
|
@ -199,43 +199,43 @@
|
||||||
(if (null? e1)
|
(if (null? e1)
|
||||||
(reverse res)
|
(reverse res)
|
||||||
(loop (car rs) (car is) (cdr e1) (cdr e2) (cdr rs) (cdr is) (cdr ds)
|
(loop (car rs) (car is) (cdr e1) (cdr e2) (cdr rs) (cdr is) (cdr ds)
|
||||||
;; complex division, imag part, real part, then denominator (reverse)
|
(let ()
|
||||||
(let ((o-real? (equal? (syntax->datum o2) 0.0))
|
(define c (car e1))
|
||||||
(e-real? (equal? (syntax->datum (car e2)) 0.0)))
|
(define d (car e2))
|
||||||
|
(define o-real? (equal? (syntax->datum b) 0.0))
|
||||||
|
(define e-real? (equal? (syntax->datum d) 0.0))
|
||||||
|
;; we have the same special cases as the Racket `/' primitive
|
||||||
|
(define d=0-case
|
||||||
|
#`(values (unsafe-fl+ (unsafe-fl/ #,a #,c)
|
||||||
|
(unsafe-fl* #,d #,b))
|
||||||
|
(unsafe-fl- (unsafe-fl/ #,b #,c)
|
||||||
|
(unsafe-fl* #,d #,a))))
|
||||||
|
(define c=0-case
|
||||||
|
#`(values (unsafe-fl+ (unsafe-fl/ #,b #,d)
|
||||||
|
(unsafe-fl* #,c #,a))
|
||||||
|
(unsafe-fl- (unsafe-fl* #,c #,b)
|
||||||
|
(unsafe-fl/ #,a #,d))))
|
||||||
|
(define general-case
|
||||||
|
#`(let ([#,(car ds) (unsafe-fl+
|
||||||
|
(unsafe-fl* #,c #,c)
|
||||||
|
(unsafe-fl* #,d #,d))])
|
||||||
|
(values (unsafe-fl/ (unsafe-fl+ (unsafe-fl* #,a #,c)
|
||||||
|
(unsafe-fl* #,b #,d))
|
||||||
|
#,(car ds))
|
||||||
|
(unsafe-fl/ (unsafe-fl- (unsafe-fl* #,b #,c)
|
||||||
|
(unsafe-fl* #,a #,d))
|
||||||
|
#,(car ds)))))
|
||||||
(cond [(and o-real? e-real?)
|
(cond [(and o-real? e-real?)
|
||||||
(list*
|
(list*
|
||||||
#`((#,(car is)) 0.0) ; currently not propagated
|
#`((#,(car is)) 0.0) ; currently not propagated
|
||||||
#`((#,(car rs)) (unsafe-fl/ #,o1 #,(car e1)))
|
#`((#,(car rs)) (unsafe-fl/ #,a #,c))
|
||||||
res)]
|
|
||||||
[o-real?
|
|
||||||
(list*
|
|
||||||
#`((#,(car is))
|
|
||||||
(unsafe-fl/ (unsafe-fl- 0.0
|
|
||||||
(unsafe-fl* #,o1 #,(car e2)))
|
|
||||||
#,(car ds)))
|
|
||||||
#`((#,(car rs)) (unsafe-fl/ (unsafe-fl* #,o1 #,(car e1))
|
|
||||||
#,(car ds)))
|
|
||||||
#`((#,(car ds)) (unsafe-fl+ (unsafe-fl* #,(car e1) #,(car e1))
|
|
||||||
(unsafe-fl* #,(car e2) #,(car e2))))
|
|
||||||
res)]
|
|
||||||
[e-real?
|
|
||||||
(list*
|
|
||||||
#`((#,(car is)) (unsafe-fl/ #,o2 #,(car e1)))
|
|
||||||
#`((#,(car rs)) (unsafe-fl/ #,o1 #,(car e1)))
|
|
||||||
res)]
|
res)]
|
||||||
[else
|
[else
|
||||||
(list*
|
;; (let-values ([(real imag) ...]) ...)
|
||||||
#`((#,(car is))
|
(list* #`[(#,(car rs) #,(car is))
|
||||||
(unsafe-fl/ (unsafe-fl- (unsafe-fl* #,o2 #,(car e1))
|
(cond [(unsafe-fl= #,d 0.0) #,d=0-case]
|
||||||
(unsafe-fl* #,o1 #,(car e2)))
|
[(unsafe-fl= #,c 0.0) #,c=0-case]
|
||||||
#,(car ds)))
|
[else #,general-case])]
|
||||||
#`((#,(car rs))
|
|
||||||
(unsafe-fl/ (unsafe-fl+ (unsafe-fl* #,o1 #,(car e1))
|
|
||||||
(unsafe-fl* #,o2 #,(car e2)))
|
|
||||||
#,(car ds)))
|
|
||||||
#`((#,(car ds))
|
|
||||||
(unsafe-fl+ (unsafe-fl* #,(car e1) #,(car e1))
|
|
||||||
(unsafe-fl* #,(car e2) #,(car e2))))
|
|
||||||
res)]))))))))
|
res)]))))))))
|
||||||
(pattern (#%plain-app (~and op (~literal /)) c1:unboxed-float-complex-opt-expr) ; unary /
|
(pattern (#%plain-app (~and op (~literal /)) c1:unboxed-float-complex-opt-expr) ; unary /
|
||||||
#:when (subtypeof? this-syntax -FloatComplex)
|
#:when (subtypeof? this-syntax -FloatComplex)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user