Calc

From WikEmacs
Jump to navigation Jump to search

Calc comes with GNU Emacs starting with version 22.

The GNU Emacs Calculator

Category Calculators -Emacs Wiki-

from emacs lisp via calc-eval

Calc may be invoked from Emacs_Lisp via calc-eval. Try these examples in a *scratch* or IELM buffer, or via a shell one-liner in batch mode.

using calc-eval

calc-eval accepts a string containing an algebraic expression as its first argument, and returns the result of evaluating the expression in a string.

;; emacs lisp
(calc-eval "sqrt(2 ^ 16)"))
;; ==> "256"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval "sqrt(2 ^ 16)"))'
# ==> 256

floating point numbers

Floats default to 12 digits of precision, with the final digit rounded.

;; emacs lisp
(calc-eval (calc-eval "2 / 3")
;; ==> "0.666666666667"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval "2 / 3"))'
# ==> 0.666666666667

Note: The shell examples use message to cause the evaluation result to be printed. In emacs lisp, printing is a side effect which only occurs when you ask for it. IELM displays the result as a convenience, and *scratch* only inserts then result depending on how you invoke it (such as with eval-print-last-sexp). message doesn't preserve quotation marks around strings because its output is intended for humans, not the lisp reader. In -batch mode, message prints to standard error, but print could be used to direct results to standard output.

lists

If the string is a comma-delimited list of expressions, then a comma-delimited list of results will be returned.

;; emacs lisp
(calc-eval "9 / 5, trunc(9 / 5), 9 % 5")
;; ==> "1.8, 1, 4"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval "9 / 5, trunc(9 / 5), 9 % 5"))'
# ==> 1.8, 1, 4

random numbers

Calc's random number generator is seeded from the system time when calc is started. random(N) returns a non-negative integer less than N. Your results should vary from the examples below.

;; emacs lisp
(calc-eval "1 + random(6), 1 + random(6), 1 + random(6)")
;; ==> "1, 4, 3"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval "1 + random(6), 1 + random(6)"))'
# ==> 5, 2

fractions

Fractions are written as NUMERATOR:DENOMINATOR to distinguish them from divison operations. Mixed fractions may be entered as WHOLE:NUMERATOR:DENOMINATOR. Fraction results are reduced to lowest terms, and may be improper fractions.

;; emacs lisp
(calc-eval "2:1:4 + 1:2")
;; ==> "11:4"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval "2:1:4 + 1:2"))'
# ==> 11:4

entering non-decimal integers

integers may be entered as RADIX#VALUE, where RADIX may range from 2 to 36 inclusive.

Caution! This is not the same notation used by emacs lisp.

;; emacs lisp
(calc-eval "2#10 * 8#10")
;; ==> "16"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval "2#10 * 8#10"))'
# ==> 16

advanced calc-eval

If the first argument to calc-eval is a list, then the first element of the list should be an algebraic expression in a string. Remaining elements of the list are zero or more NAME VALUE pairs which specify mode settings.

Important: In emacs lisp '(foo) is a quoted list, but ' (apostrophe) is special to the shell. Lisp expressions in previous shell examples were wrapped in ' (apostrophe) symbols to prevent the shell from interpreting them. In the following shell examples, (quote (foo bar)) makes a quoted list without breaking the shell quoting.

non-decimal integer results

;; emacs lisp
(calc-eval '("2 * 8" calc-number-radix 16))
;;  ==> "16#10"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval (quote ("20" calc-number-radix 16))))'
# ==> 16#14

setting numeric precision

;; emacs lisp
(calc-eval '("2 / 3" calc-internal-prec 20))
;; ==> "0.66666666666666666667"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval (quote ("2 / 3" calc-internal-prec 20))))'
# ==> 0.66666666666666666667

setting angular mode

;; emacs lisp
(calc-eval '("arctan2(0, -1)" calc-internal-prec 20 calc-angle-mode rad))
;; ==> "3.1415926535897932385"
# shell
emacs -Q -batch --eval='(message "%s" (calc-eval (quote ("arctan2(0, -1)" calc-angle-mode rad))))'
# ==> 3.14159265359