Raymond Toy pushed to branch issue-461-cdiv-use-4-doubles at cmucl / cmucl

Commits:

1 changed file:

Changes:

  • src/code/numbers.lisp
    ... ... @@ -729,59 +729,58 @@
    729 729
            (defun ,internal (a b c d)
    
    730 730
     	 (declare (,type a b c d)
    
    731 731
     		  ,@opt)
    
    732
    -	 (let ()
    
    733
    -	   (flet ((maybe-scale (abs-tst a b c d)
    
    734
    -		    (declare (,type a b c d))
    
    735
    -		    ;; This implements McGehearty's iteration 3 to
    
    736
    -		    ;; handle the case when some values are too big
    
    737
    -		    ;; and should be scaled down.  Also if some
    
    738
    -		    ;; values are too tiny, scale them up.
    
    739
    -		    (let ((abs-a (abs a))
    
    740
    -			  (abs-b (abs b)))
    
    741
    -		      (if (or (> abs-tst ,+rbig+)
    
    742
    -			      (> abs-a ,+rbig+)
    
    743
    -			      (> abs-b ,+rbig+))
    
    744
    -			  (setf a (* a 0.5d0)
    
    745
    -				b (* b 0.5d0)
    
    746
    -				c (* c 0.5d0)
    
    747
    -				d (* d 0.5d0))
    
    748
    -			  (if (< abs-tst ,+rmin2+)
    
    749
    -			      (setf a (* a ,+rminscal+)
    
    750
    -				    b (* b ,+rminscal+)
    
    751
    -				    c (* c ,+rminscal+)
    
    752
    -				    d (* d ,+rminscal+))
    
    753
    -			      (if (or (and (< abs-a ,+rmin+)
    
    754
    -					   (< abs-b ,+rmax2+)
    
    755
    -					   (< abs-tst ,+rmax2+))
    
    756
    -				      (and (< abs-b ,+rmin+)
    
    757
    -					   (< abs-a ,+rmax2+)
    
    758
    -					   (< abs-tst ,+rmax2+)))
    
    759
    -				  (setf a (* a ,+rminscal+)
    
    760
    -					b (* b ,+rminscal+)
    
    761
    -					c (* c ,+rminscal+)
    
    762
    -					d (* d ,+rminscal+)))))
    
    763
    -		      (values a b c d))))
    
    764
    -	     (cond
    
    765
    -	       ((<= (abs d) (abs c))
    
    766
    -		;; |d| <= |c|, so we can use robust-subinternal to
    
    767
    -		;; perform the division.
    
    768
    -		(multiple-value-bind (a b c d)
    
    769
    -		    (maybe-scale (abs c) a b c d)
    
    770
    -		  (,subinternal a b c d)))
    
    771
    -	       (t
    
    772
    -		;; |d| > |c|.  So, instead compute
    
    773
    -		;;
    
    774
    -		;;   (b + i*a)/(d + i*c) = ((b*d+a*c) + (a*d-b*c)*i)/(d^2+c^2)
    
    775
    -		;;
    
    776
    -		;; Compare this to (a+i*b)/(c+i*d) and we see that
    
    777
    -		;; realpart of the former is the same, but the
    
    778
    -		;; imagpart of the former is the negative of the
    
    779
    -		;; desired division.
    
    780
    -		(multiple-value-bind (a b c d)
    
    781
    -		    (maybe-scale (abs d) a b c d)
    
    782
    -		  (multiple-value-bind (e f)
    
    783
    -		      (,subinternal b a d c)
    
    784
    -		    (values e (- f)))))))))
    
    732
    +	 (flet ((maybe-scale (abs-tst a b c d)
    
    733
    +		  (declare (,type a b c d))
    
    734
    +		  ;; This implements McGehearty's iteration 3 to
    
    735
    +		  ;; handle the case when some values are too big
    
    736
    +		  ;; and should be scaled down.  Also if some
    
    737
    +		  ;; values are too tiny, scale them up.
    
    738
    +		  (let ((abs-a (abs a))
    
    739
    +			(abs-b (abs b)))
    
    740
    +		    (if (or (> abs-tst ,+rbig+)
    
    741
    +			    (> abs-a ,+rbig+)
    
    742
    +			    (> abs-b ,+rbig+))
    
    743
    +			(setf a (* a 0.5d0)
    
    744
    +			      b (* b 0.5d0)
    
    745
    +			      c (* c 0.5d0)
    
    746
    +			      d (* d 0.5d0))
    
    747
    +			(if (< abs-tst ,+rmin2+)
    
    748
    +			    (setf a (* a ,+rminscal+)
    
    749
    +				  b (* b ,+rminscal+)
    
    750
    +				  c (* c ,+rminscal+)
    
    751
    +				  d (* d ,+rminscal+))
    
    752
    +			    (if (or (and (< abs-a ,+rmin+)
    
    753
    +					 (< abs-b ,+rmax2+)
    
    754
    +					 (< abs-tst ,+rmax2+))
    
    755
    +				    (and (< abs-b ,+rmin+)
    
    756
    +					 (< abs-a ,+rmax2+)
    
    757
    +					 (< abs-tst ,+rmax2+)))
    
    758
    +				(setf a (* a ,+rminscal+)
    
    759
    +				      b (* b ,+rminscal+)
    
    760
    +				      c (* c ,+rminscal+)
    
    761
    +				      d (* d ,+rminscal+)))))
    
    762
    +		    (values a b c d))))
    
    763
    +	   (cond
    
    764
    +	     ((<= (abs d) (abs c))
    
    765
    +	      ;; |d| <= |c|, so we can use robust-subinternal to
    
    766
    +	      ;; perform the division.
    
    767
    +	      (multiple-value-bind (a b c d)
    
    768
    +		  (maybe-scale (abs c) a b c d)
    
    769
    +		(,subinternal a b c d)))
    
    770
    +	     (t
    
    771
    +	      ;; |d| > |c|.  So, instead compute
    
    772
    +	      ;;
    
    773
    +	      ;;   (b + i*a)/(d + i*c) = ((b*d+a*c) + (a*d-b*c)*i)/(d^2+c^2)
    
    774
    +	      ;;
    
    775
    +	      ;; Compare this to (a+i*b)/(c+i*d) and we see that
    
    776
    +	      ;; realpart of the former is the same, but the
    
    777
    +	      ;; imagpart of the former is the negative of the
    
    778
    +	      ;; desired division.
    
    779
    +	      (multiple-value-bind (a b c d)
    
    780
    +		  (maybe-scale (abs d) a b c d)
    
    781
    +		(multiple-value-bind (e f)
    
    782
    +		    (,subinternal b a d c)
    
    783
    +		  (values e (- f))))))))
    
    785 784
            (defun ,name (a b c d)
    
    786 785
     	 ,docstring
    
    787 786
     	 (declare (,type a b c d)