Raymond Toy pushed to branch issue-456-more-accurate-complex-div at cmucl / cmucl

Commits:

3 changed files:

Changes:

  • src/code/numbers.lisp
    ... ... @@ -635,7 +635,7 @@
    635 635
     	   ;; Thus tt = (c + d*r).
    
    636 636
     	   (cond ((>= (abs r) +rmin+)
    
    637 637
     		  (let ((br (* b r)))
    
    638
    -		    (if (/= br 0)
    
    638
    +		    (if (/= br 0d0)
    
    639 639
     			(/ (+ a br) tt)
    
    640 640
     			;; b*r underflows.  Instead, compute
    
    641 641
     			;;
    
    ... ... @@ -726,28 +726,26 @@
    726 726
     		    (multiple-value-bind (e f)
    
    727 727
     			(robust-subinternal b a d c)
    
    728 728
     		      (complex e (- f))))))))))
    
    729
    -      (let* ((a (realpart x))
    
    730
    -	     (b (imagpart x))
    
    731
    -	     (c (realpart y))
    
    732
    -	     (d (imagpart y))
    
    733
    -	     (ab (max (abs a) (abs b)))
    
    734
    -	     (cd (max (abs c) (abs d)))
    
    729
    +      (let* ((max-ab (max (abs (realpart x))
    
    730
    +			  (abs (imagpart x))))
    
    731
    +	     (max-cd (max (abs (realpart y))
    
    732
    +			  (abs (imagpart y))))
    
    735 733
     	     (s 1d0))
    
    736 734
     	(declare (double-float s))
    
    737 735
     	;; If a or b is big, scale down a and b.
    
    738
    -	(when (>= ab +rbig+)
    
    739
    -	  (setf x (/ x 2)
    
    740
    -		s (* s 2)))
    
    736
    +	(when (>= max-ab +rbig+)
    
    737
    +	  (setf x (/ x 2d0)
    
    738
    +		s (* s 2d0)))
    
    741 739
     	;; If c or d is big, scale down c and d.
    
    742
    -	(when (>= cd +rbig+)
    
    743
    -	  (setf y (/ y 2)
    
    744
    -		s (/ s 2)))
    
    740
    +	(when (>= max-cd +rbig+)
    
    741
    +	  (setf y (/ y 2d0)
    
    742
    +		s (/ s 2d0)))
    
    745 743
     	;; If a or b is tiny, scale up a and b.
    
    746
    -	(when (<= ab (* +rmin+ +2/eps+))
    
    744
    +	(when (<= max-ab (* +rmin+ +2/eps+))
    
    747 745
     	  (setf x (* x +be+)
    
    748 746
     		s (/ s +be+)))
    
    749 747
     	;; If c or d is tiny, scale up c and d.
    
    750
    -	(when (<= cd (* +rmin+ +2/eps+))
    
    748
    +	(when (<= max-cd (* +rmin+ +2/eps+))
    
    751 749
     	  (setf y (* y +be+)
    
    752 750
     		s (* s +be+)))
    
    753 751
     	(* s
    
    ... ... @@ -909,6 +907,7 @@
    909 907
            (build-ratio (maybe-truncate nx gcd)
    
    910 908
     		    (* (maybe-truncate y gcd) (denominator x)))))))
    
    911 909
     
    
    910
    +
    
    912 911
     (defun %negate (n)
    
    913 912
       (number-dispatch ((n number))
    
    914 913
         (((foreach fixnum single-float double-float #+long-float long-float))
    

  • src/general-info/release-22a.md
    ... ... @@ -35,6 +35,8 @@ public domain.
    35 35
                 defpackage with errno symbols
    
    36 36
         * #453: Use correct flags for analyzer and always save logs.
    
    37 37
         * #456: Improve accuracy for division of complex double-floats
    
    38
    +            using Baudin and Smith's robust complex division algorithm
    
    39
    +            with improvements by Patrick McGehearty.
    
    38 40
         * #458: Spurious overflow in double-double-float multiply
    
    39 41
       * Other changes:
    
    40 42
       * Improvements to the PCL implementation of CLOS:
    

  • tests/float.lisp
    ... ... @@ -354,7 +354,7 @@
    354 354
     ;; Rudimentary code to read C %a formatted numbers that look like
    
    355 355
     ;; "-0x1.c4dba4ba1ee79p-620".  We assume STRING is exactly in this
    
    356 356
     ;; format.  No error-checking is done.
    
    357
    -(defun parse-%a (string)
    
    357
    +(defun parse-hex-float (string)
    
    358 358
       (let* ((sign (if (char= (aref string 0) #\-)
    
    359 359
     		   -1
    
    360 360
     		   1))
    
    ... ... @@ -445,30 +445,43 @@
    445 445
        ;; 13
    
    446 446
        ;; Iteration 1.  Without this, we would instead return
    
    447 447
        ;;
    
    448
    -   ;;   (complex (parse-%a "0x1.ba8df8075bceep+155") (parse-%a "-0x1.a4ad6329485f0p-895"))
    
    448
    +   ;;   (complex (parse-hex-float "0x1.ba8df8075bceep+155")
    
    449
    +   ;;            (parse-hex-float "-0x1.a4ad6329485f0p-895"))
    
    449 450
        ;;
    
    450 451
        ;; whose imaginary part is quite a bit off.
    
    451
    -   (list (complex (parse-%a "0x1.73a3dac1d2f1fp+509") (parse-%a "-0x1.c4dba4ba1ee79p-620"))
    
    452
    -	 (complex (parse-%a "0x1.adf526c249cf0p+353") (parse-%a "0x1.98b3fbc1677bbp-697"))
    
    453
    -	 (complex (parse-%a "0x1.BA8DF8075BCEEp+155") (parse-%a "-0x1.A4AD628DA5B74p-895"))
    
    452
    +   (list (complex (parse-hex-float "0x1.73a3dac1d2f1fp+509")
    
    453
    +		  (parse-hex-float "-0x1.c4dba4ba1ee79p-620"))
    
    454
    +	 (complex (parse-hex-float "0x1.adf526c249cf0p+353")
    
    455
    +		  (parse-hex-float "0x1.98b3fbc1677bbp-697"))
    
    456
    +	 (complex (parse-hex-float "0x1.BA8DF8075BCEEp+155")
    
    457
    +		  (parse-hex-float "-0x1.A4AD628DA5B74p-895"))
    
    454 458
     	 53)
    
    455 459
        ;; 14
    
    456 460
        ;; Iteration 2.
    
    457
    -   (list (complex (parse-%a "-0x0.000000008e4f8p-1022") (parse-%a "0x0.0000060366ba7p-1022"))
    
    458
    -	 (complex (parse-%a "-0x1.605b467369526p-245") (parse-%a "0x1.417bd33105808p-256"))
    
    459
    -	 (complex (parse-%a "0x1.cde593daa4ffep-810") (parse-%a "-0x1.179b9a63df6d3p-799"))
    
    461
    +   (list (complex (parse-hex-float "-0x0.000000008e4f8p-1022")
    
    462
    +		  (parse-hex-float "0x0.0000060366ba7p-1022"))
    
    463
    +	 (complex (parse-hex-float "-0x1.605b467369526p-245")
    
    464
    +		  (parse-hex-float "0x1.417bd33105808p-256"))
    
    465
    +	 (complex (parse-hex-float "0x1.cde593daa4ffep-810")
    
    466
    +		  (parse-hex-float "-0x1.179b9a63df6d3p-799"))
    
    460 467
     	 52)
    
    461 468
        ;; 15
    
    462 469
        ;; Iteration 3
    
    463
    -   (list (complex (parse-%a "0x1.cb27eece7c585p-355 ") (parse-%a "0x0.000000223b8a8p-1022"))
    
    464
    -	 (complex (parse-%a "-0x1.74e7ed2b9189fp-22") (parse-%a "0x1.3d80439e9a119p-731"))
    
    465
    -	 (complex (parse-%a "-0x1.3b35ed806ae5ap-333") (parse-%a "-0x0.05e01bcbfd9f6p-1022"))
    
    470
    +   (list (complex (parse-hex-float "0x1.cb27eece7c585p-355 ")
    
    471
    +		  (parse-hex-float "0x0.000000223b8a8p-1022"))
    
    472
    +	 (complex (parse-hex-float "-0x1.74e7ed2b9189fp-22")
    
    473
    +		  (parse-hex-float "0x1.3d80439e9a119p-731"))
    
    474
    +	 (complex (parse-hex-float "-0x1.3b35ed806ae5ap-333")
    
    475
    +		  (parse-hex-float "-0x0.05e01bcbfd9f6p-1022"))
    
    466 476
     	 53)
    
    467 477
        ;; 16
    
    468 478
        ;; Iteration 4
    
    469
    -   (list (complex (parse-%a "-0x1.f5c75c69829f0p-530") (parse-%a "-0x1.e73b1fde6b909p+316"))
    
    470
    -	 (complex (parse-%a "-0x1.ff96c3957742bp+1023") (parse-%a "0x1.5bd78c9335899p+1021"))
    
    471
    -	 (complex (parse-%a "-0x1.423c6ce00c73bp-710") (parse-%a "0x1.d9edcf45bcb0ep-708"))
    
    479
    +   (list (complex (parse-hex-float "-0x1.f5c75c69829f0p-530")
    
    480
    +		  (parse-hex-float "-0x1.e73b1fde6b909p+316"))
    
    481
    +	 (complex (parse-hex-float "-0x1.ff96c3957742bp+1023")
    
    482
    +		  (parse-hex-float "0x1.5bd78c9335899p+1021"))
    
    483
    +	 (complex (parse-hex-float "-0x1.423c6ce00c73bp-710")
    
    484
    +		  (parse-hex-float "0x1.d9edcf45bcb0ep-708"))
    
    472 485
     	 52)
    
    473 486
        ))
    
    474 487