summaryrefslogtreecommitdiff
path: root/lisp/calc
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/calc')
-rw-r--r--lisp/calc/calc-forms.el2
-rw-r--r--lisp/calc/calc-lang.el35
-rw-r--r--lisp/calc/calc-units.el27
-rw-r--r--lisp/calc/calc.el9
4 files changed, 66 insertions, 7 deletions
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index 96cc74f7ef6..dfc5dfc6588 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -444,7 +444,7 @@
(defun math-this-year ()
- (string-to-number (substring (current-time-string) -4)))
+ (nth 5 (decode-time)))
(defun math-leap-year-p (year)
(if (Math-lessp year 1752)
diff --git a/lisp/calc/calc-lang.el b/lisp/calc/calc-lang.el
index c53f59eb0f4..ec4c497a1c6 100644
--- a/lisp/calc/calc-lang.el
+++ b/lisp/calc/calc-lang.el
@@ -133,8 +133,39 @@
( asin . calcFunc-arcsin )
( asinh . calcFunc-arcsinh )
( atan . calcFunc-arctan )
- ( atan2 . calcFunc-arctan2 )
- ( atanh . calcFunc-arctanh )))
+ ( atan2 . calcFunc-arctan2 )
+ ( atanh . calcFunc-arctanh )
+ ( fma . (math-C-parse-fma))
+ ( fmax . calcFunc-max )
+ ( j0 . (math-C-parse-bess))
+ ( jn . calcFunc-besJ )
+ ( j1 . (math-C-parse-bess))
+ ( yn . calcFunc-besY )
+ ( y0 . (math-C-parse-bess))
+ ( y1 . (math-C-parse-bess))
+ ( tgamma . calcFunc-gamma )))
+
+(defun math-C-parse-bess (f val)
+ "Parse C's j0, j1, y0, y1 functions."
+ (let ((args (math-read-expr-list)))
+ (math-read-token)
+ (append
+ (cond ((eq val 'j0) '(calcFunc-besJ 0))
+ ((eq val 'j1) '(calcFunc-besJ 1))
+ ((eq val 'y0) '(calcFunc-besY 0))
+ ((eq val 'y1) '(calcFunc-besY 1)))
+ args)))
+
+(defun math-C-parse-fma (f val)
+ "Parse C's fma function fma(x,y,z) => (x * y + z)."
+ (let ((args (math-read-expr-list)))
+ (math-read-token)
+ (list 'calcFunc-add
+ (list 'calcFunc-mul
+ (nth 0 args)
+ (nth 1 args))
+ (nth 2 args))))
+
(put 'c 'math-variable-table
'( ( M_PI . var-pi )
diff --git a/lisp/calc/calc-units.el b/lisp/calc/calc-units.el
index 9d2583085a2..e5c7b6737fb 100644
--- a/lisp/calc/calc-units.el
+++ b/lisp/calc/calc-units.el
@@ -356,6 +356,8 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(math-to-standard-units (calc-top-n 1)
nil))))))
+(defvar calc-ensure-consistent-units)
+
(defun calc-quick-units ()
(interactive)
(calc-slow-wrapper
@@ -370,8 +372,11 @@ Entries are (SYMBOL EXPR DOC-STRING TEMP-TYPE BASE-UNITS).")
(unless (< pos (length units))
(error "Unit number %d not defined" pos))
(if (math-units-in-expr-p expr nil)
- (calc-enter-result 1 (format "cun%d" num)
- (math-convert-units expr (nth pos units)))
+ (progn
+ (if calc-ensure-consistent-units
+ (math-check-unit-consistency expr (nth pos units)))
+ (calc-enter-result 1 (format "cun%d" num)
+ (math-convert-units expr (nth pos units))))
(calc-enter-result 1 (format "*un%d" num)
(math-simplify-units
(math-mul expr (nth pos units))))))))
@@ -477,6 +482,8 @@ If EXPR is nil, return nil."
(setq units (math-read-expr new-units))
(when (eq (car-safe units) 'error)
(error "Bad format in units expression: %s" (nth 2 units)))
+ (if calc-ensure-consistent-units
+ (math-check-unit-consistency expr units))
(math-put-default-units units)
(let ((unew (math-units-in-expr-p units t))
(std (and (eq (car-safe units) 'var)
@@ -560,7 +567,7 @@ If EXPR is nil, return nil."
(defun calc-extract-units ()
(interactive)
(calc-slow-wrapper
- (calc-enter-result 1 "rmun" (math-simplify-units
+ (calc-enter-result 1 "exun" (math-simplify-units
(math-extract-units (calc-top-n 1))))))
;; The variables calc-num-units and calc-den-units are local to
@@ -914,6 +921,20 @@ If EXPR is nil, return nil."
(math-single-units-in-expr-p (nth 1 expr))))
(t 'wrong)))
+(defun math-consistent-units-p (expr newunits)
+ "Non-nil if EXPR and NEWUNITS have consistent units."
+ (or
+ (and (eq (car-safe newunits) 'var)
+ (assq (nth 1 newunits) math-standard-units-systems))
+ (math-numberp (math-get-units (list '/ expr newunits)))))
+
+(defun math-check-unit-consistency (expr units)
+ "Give an error if EXPR and UNITS do not have consistent units."
+ (unless (math-consistent-units-p expr units)
+ (error "New units (%s) are inconsistent with current units (%s)"
+ (math-format-value units)
+ (math-format-value (math-get-units expr)))))
+
(defun math-check-unit-name (v)
(and (eq (car-safe v) 'var)
(or (assq (nth 1 v) (or math-units-table (math-build-units-table)))
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 5224d1aa4f8..4d64209dd36 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -222,7 +222,7 @@
(defgroup calc nil
- "GNU Calc."
+ "Advanced desk calculator and mathematical tool."
:prefix "calc-"
:tag "Calc"
:group 'applications)
@@ -418,6 +418,13 @@ in normal mode."
:group 'calc
:type 'boolean)
+(defcustom calc-ensure-consistent-units
+ nil
+ "If non-nil, make sure new units are consistent with current units
+when converting units."
+ :group 'calc
+ :type 'boolean)
+
(defcustom calc-undo-length
100
"The number of undo steps that will be preserved when Calc is quit."