Raymond Toy pushed to branch issue-456-more-accurate-complex-div at cmucl / cmucl
Commits:
-
e65f9f5c
by Raymond Toy at 2025-12-17T07:04:10-08:00
-
6034f935
by Raymond Toy at 2025-12-17T07:04:10-08:00
-
10efd37c
by Raymond Toy at 2025-12-17T07:12:47-08:00
-
c6c3c48f
by Raymond Toy at 2025-12-17T07:25:38-08:00
-
c09d2252
by Raymond Toy at 2025-12-17T07:27:33-08:00
6 changed files:
- src/code/exports.lisp
- src/code/extensions.lisp
- src/code/numbers.lisp
- src/i18n/locale/cmucl.pot
- tests/float.lisp
- tests/pathname.lisp
Changes:
| ... | ... | @@ -1213,7 +1213,8 @@ |
| 1213 | 1213 | |
| 1214 | 1214 | "INVALID-FASL"
|
| 1215 | 1215 | "WITH-TEMPORARY-DIRECTORY"
|
| 1216 | - "WITH-TEMPORARY-FILE")
|
|
| 1216 | + "WITH-TEMPORARY-FILE"
|
|
| 1217 | + "DELETE-DIRECTORY")
|
|
| 1217 | 1218 | ;; gencgc features
|
| 1218 | 1219 | #+gencgc
|
| 1219 | 1220 | (:export "GET-GC-ASSERTIONS"
|
| ... | ... | @@ -673,9 +673,9 @@ |
| 673 | 673 | (defun delete-directory (dirname &key recursive)
|
| 674 | 674 | _N"Delete the directory Dirname. If the Recursive is non-NIL,
|
| 675 | 675 | recursively delete the directory Dirname including all files and
|
| 676 | - subdirectories. Dirname must be a pathname to a directory. Any NAME
|
|
| 677 | - or TYPE components in Dirname are ignored."
|
|
| 678 | - (declare (type pathname dirname))
|
|
| 676 | + subdirectories. Dirname must name a directory. Any NAME or TYPE
|
|
| 677 | + components in Dirname are ignored. A FILE-ERROR is signaled if any
|
|
| 678 | + directory cannot be deleted."
|
|
| 679 | 679 | (when recursive
|
| 680 | 680 | ;; Find all the files or directories in DIRNAME.
|
| 681 | 681 | (dolist (path (directory (merge-pathnames "*.*" dirname)))
|
| ... | ... | @@ -685,8 +685,15 @@ |
| 685 | 685 | (delete-directory path :recursive t)
|
| 686 | 686 | (delete-file path))))
|
| 687 | 687 | ;; Finally delete the directory.
|
| 688 | - (unix:unix-rmdir (namestring dirname))
|
|
| 689 | - (values))
|
|
| 688 | + (multiple-value-bind (ok errno)
|
|
| 689 | + (unix:unix-rmdir (namestring dirname))
|
|
| 690 | + (unless ok
|
|
| 691 | + (error 'kernel:simple-file-error
|
|
| 692 | + :pathname dirname
|
|
| 693 | + :format-control (intl:gettext "Could not remove directory \"~A\": ~A.")
|
|
| 694 | + :format-arguments (list dirname
|
|
| 695 | + (unix:get-unix-error-msg errno))))
|
|
| 696 | + ok))
|
|
| 690 | 697 | |
| 691 | 698 | |
| 692 | 699 | ;;; WITH-TEMPORARY-DIRECTORY -- Public
|
| ... | ... | @@ -602,16 +602,17 @@ |
| 602 | 602 | ;; In particular iteration 1 and 3 are added. Iteration 2 and 4 were
|
| 603 | 603 | ;; not added. The test examples from iteration 2 and 4 didn't change
|
| 604 | 604 | ;; with or without changes added.
|
| 605 | -(let* ((+eps+ (scale-float 1d0 -52))
|
|
| 606 | - (+rmin+ least-positive-normalized-double-float)
|
|
| 605 | +(let* ((+rmin+ least-positive-normalized-double-float)
|
|
| 607 | 606 | (+rbig+ (/ most-positive-double-float 2))
|
| 608 | 607 | (+rmin2+ (scale-float 1d0 -53))
|
| 609 | 608 | (+rminscal+ (scale-float 1d0 51))
|
| 610 | 609 | (+rmax2+ (* +rbig+ +rmin2+))
|
| 610 | + ;; The value of %eps in Scilab
|
|
| 611 | + (+eps+ (scale-float 1d0 -52))
|
|
| 611 | 612 | (+be+ (/ 2 (* +eps+ +eps+)))
|
| 612 | 613 | (+2/eps+ (/ 2 +eps+)))
|
| 613 | - (declare (double-float +eps+ +rmin+ +rbig+ +rmin2+
|
|
| 614 | - +rminscal+ +rmax2+ +be+ +2/eps+))
|
|
| 614 | + (declare (double-float +rmin+ +rbig+ +rmin2+ +rminscal+ +rmax2+
|
|
| 615 | + +eps+ +be+ +2/eps+))
|
|
| 615 | 616 | (defun cdiv-double-float (x y)
|
| 616 | 617 | (declare (type (complex double-float) x y)
|
| 617 | 618 | (optimize (speed 3) (safety 0)))
|
| ... | ... | @@ -619,7 +620,7 @@ |
| 619 | 620 | ((internal-compreal (a b c d r tt)
|
| 620 | 621 | (declare (double-float a b c d r tt))
|
| 621 | 622 | ;; Compute the real part of the complex division
|
| 622 | - ;; (a+ib)/(c+id), assuming |c| <= |d|. r = d/c and tt = 1/(c+d*r).
|
|
| 623 | + ;; (a+ib)/(c+id), assuming |d| <= |c|. r = d/c and tt = 1/(c+d*r).
|
|
| 623 | 624 | ;;
|
| 624 | 625 | ;; The realpart is (a*c+b*d)/(c^2+d^2).
|
| 625 | 626 | ;;
|
| ... | ... | @@ -713,7 +714,8 @@ |
| 713 | 714 | (t
|
| 714 | 715 | ;; |d| > |c|. So, instead compute
|
| 715 | 716 | ;;
|
| 716 | - ;; (b + i*a)/(d + i*c) = ((b*d+a*c) + (a*d-b*c)*i)/(d^2+c^2)
|
|
| 717 | + ;; (b + i*a)/(d + i*c)
|
|
| 718 | + ;; = ((b*d+a*c) + (a*d-b*c)*i)/(d^2+c^2)
|
|
| 717 | 719 | ;;
|
| 718 | 720 | ;; Compare this to (a+i*b)/(c+i*d) and we see that
|
| 719 | 721 | ;; realpart of the former is the same, but the
|
| ... | ... | @@ -850,7 +852,7 @@ |
| 850 | 852 | (((complex rational)
|
| 851 | 853 | (complex rational))
|
| 852 | 854 | ;; We probably don't need to do Smith's algorithm for rationals.
|
| 853 | - ;; A naive implementation of coplex division has no issues.
|
|
| 855 | + ;; A naive implementation of complex division has no issues.
|
|
| 854 | 856 | (let ((a (realpart x))
|
| 855 | 857 | (b (imagpart x))
|
| 856 | 858 | (c (realpart y))
|
| ... | ... | @@ -6011,8 +6011,13 @@ msgstr "" |
| 6011 | 6011 | msgid ""
|
| 6012 | 6012 | "Delete the directory Dirname. If the Recursive is non-NIL,\n"
|
| 6013 | 6013 | " recursively delete the directory Dirname including all files and\n"
|
| 6014 | -" subdirectories. Dirname must be a pathname to a directory. Any NAME\n"
|
|
| 6015 | -" or TYPE components in Dirname are ignored."
|
|
| 6014 | +" subdirectories. Dirname must name a directory. Any NAME or TYPE\n"
|
|
| 6015 | +" components in Dirname are ignored. A FILE-ERROR is signaled if any\n"
|
|
| 6016 | +" directory cannot be deleted."
|
|
| 6017 | +msgstr ""
|
|
| 6018 | + |
|
| 6019 | +#: src/code/extensions.lisp
|
|
| 6020 | +msgid "Could not remove directory \"~A\": ~A."
|
|
| 6016 | 6021 | msgstr ""
|
| 6017 | 6022 | |
| 6018 | 6023 | #: src/code/extensions.lisp
|
| ... | ... | @@ -343,8 +343,6 @@ |
| 343 | 343 | (assert-true (typep new-mode 'x86::float-modes))
|
| 344 | 344 | (assert-equal new-mode (setf (x86::x87-floating-point-modes) new-mode))))
|
| 345 | 345 | |
| 346 | - |
|
| 347 | - |
|
| 348 | 346 | ;; Issue #458
|
| 349 | 347 | (define-test dd-mult-overflow
|
| 350 | 348 | (:tag :issues)
|
| ... | ... | @@ -144,14 +144,13 @@ |
| 144 | 144 | (assert-equal dir-tilde dir-home))))
|
| 145 | 145 | |
| 146 | 146 | (define-test delete-directory
|
| 147 | - (let ((dir (ensure-directories-exist "tmp/a/b/c/")))
|
|
| 148 | - ;; Verify that the directories were created.
|
|
| 149 | - (assert-equal "tmp/a/b/c/"
|
|
| 150 | - dir)
|
|
| 151 | - ;; Try to delete the directory. It should fail, which we verify
|
|
| 152 | - ;; by noting the directory listing is not empty.
|
|
| 153 | - (ext::delete-directory (pathname "tmp/"))
|
|
| 154 | - (assert-true (directory "tmp/"))
|
|
| 155 | - ;; Now recursively delete the directory.
|
|
| 156 | - (ext::delete-directory (pathname "tmp/") :recursive t)
|
|
| 157 | - (assert-false (directory "tmp/")))) |
|
| 147 | + (:tag :issues)
|
|
| 148 | + (ext:with-temporary-directory (path)
|
|
| 149 | + (let ((dir (ensure-directories-exist (merge-pathnames "tmp/a/b/c/" path))))
|
|
| 150 | + ;; Try to delete the directory. It should fail..
|
|
| 151 | + (assert-error 'kernel:simple-file-error
|
|
| 152 | + (ext:delete-directory (merge-pathnames "tmp/" path)))
|
|
| 153 | + ;; Now recursively delete the directory.
|
|
| 154 | + (assert-true (ext:delete-directory (merge-pathnames "tmp/" path)
|
|
| 155 | + :recursive t))
|
|
| 156 | + (assert-false (directory "tmp/"))))) |