Difference between revisions of "Calc"

From WikEmacs
Jump to navigation Jump to search
(Add Link)
Line 4: Line 4:
  
 
[http://www.emacswiki.org/emacs/CategoryCalculators Category Calculators -Emacs Wiki-]
 
[http://www.emacswiki.org/emacs/CategoryCalculators Category Calculators -Emacs Wiki-]
 +
 +
== from emacs lisp via calc-eval ==
 +
 +
Calc may be invoked from [[Emacs_Lisp]] via [https://www.gnu.org/software/emacs/manual/html_node/calc/Calling-Calc-from-Your-Programs.html#Calling-Calc-from-Your-Programs calc-eval]. Try these examples in a ''*scratch*'' or [[IELM]] buffer, or via a shell one-liner in [https://www.gnu.org/software/emacs/manual/html_node/emacs/Initial-Options.html#Initial-Options batch mode].
 +
 +
=== using calc-eval ===
 +
 +
''calc-eval'' accepts a string containing an [https://www.gnu.org/software/emacs/manual/html_node/calc/Algebraic-Entry.html#Algebraic-Entry algebraic expression] as its first argument, and returns the result of evaluating the expression in a string.
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval "sqrt(2 ^ 16)"))
 +
;; ==> "256"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval "sqrt(2 ^ 16)"))'
 +
# ==> 256
 +
</source>
 +
 +
=== floating point numbers ===
 +
 +
[https://www.gnu.org/software/emacs/manual/html_node/calc/Floats.html#Floats Floats] default to 12 digits of [https://www.gnu.org/software/emacs/manual/html_node/calc/Precision.html#Precision precision], with the final digit rounded.
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval (calc-eval "2 / 3")
 +
;; ==> "0.666666666667"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval "2 / 3"))'
 +
# ==> 0.666666666667
 +
</source>
 +
 +
'''Note:''' The shell example uses ''message'' to cause the result to be printed. In ''-batch'' mode, ''message'' prints to standard output. In emacs lisp, printing is a [https://en.wikipedia.org/wiki/Side_effect_%28computer_science%29 side effect] which only occurs when you ask for it. ''IELM'' displays evaluation results as a convenience, and ''*scratch*'' only inserts evaluation results depending on how you invoke it (such as with [https://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Interaction.html#Lisp-Interaction eval-print-last-sexp]). ''message'' doesn't preserve quotation marks around strings because its output is intended for humans, not the lisp reader.
 +
 +
=== lists ===
 +
 +
If the string is a comma-delimited list of expressions, then a comma-delimited list of results will be returned.
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval "9 / 5, trunc(9 / 5), 9 % 5")
 +
;; ==> "1.8, 1, 4"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval "9 / 5, trunc(9 / 5), 9 % 5"))'
 +
# ==> 1.8, 1, 4
 +
</source>
 +
 +
=== random numbers ===
 +
 +
[https://www.gnu.org/software/emacs/manual/html_node/calc/Random-Numbers.html#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.
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval "1 + random(6), 1 + random(6), 1 + random(6)")
 +
;; ==> "1, 4, 3"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval "1 + random(6), 1 + random(6)"))'
 +
# ==> 5, 2
 +
</source>
 +
 +
=== fractions ===
 +
 +
[https://www.gnu.org/software/emacs/manual/html_node/calc/Fractions.html#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.
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval "2:1:4 + 1:2")
 +
;; ==> "11:4"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval "2:1:4 + 1:2"))'
 +
# ==> 11:4
 +
</source>
 +
 +
=== entering non-decimal integers ===
 +
 +
[https://www.gnu.org/software/emacs/manual/html_node/calc/Integers.html#Integers integers] may be entered as ''RADIX#VALUE'', where ''RADIX'' may range from 2 to 36 inclusive.
 +
 +
'''Caution!''' This is '''not''' the same [https://www.gnu.org/software/emacs/manual/html_node/elisp/Integer-Basics.html#Integer-Basics notation used by emacs lisp].
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval "2#10 * 8#10")
 +
;; ==> "16"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval "2#10 * 8#10"))'
 +
# ==> 16
 +
</source>
 +
 +
== 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 [https://www.gnu.org/software/emacs/manual/html_node/calc/Mode-Settings.html#Mode-Settings mode settings].
 +
 +
'''Important:''' In emacs lisp <nowiki>'(foo)</nowiki> is a [https://www.gnu.org/software/emacs/manual/html_node/elisp/Quoting.html#Quoting quoted] list, but <nowiki>'</nowiki> (apostrophe) is special to the shell. Lisp expressions in previous shell examples were wrapped in <nowiki>'</nowiki> (apostrophe) symbols to prevent the shell from interpreting them. In the following shell examples, ''(quote (foo bar))'' makes a quoted list without breaking the [https://www.gnu.org/software/bash/manual/html_node/Quoting.html#Quoting shell quoting].
 +
 +
=== non-decimal integer results ===
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval '("2 * 8" calc-number-radix 16))
 +
;;  ==> "16#10"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval (quote ("20" calc-number-radix 16))))'
 +
# ==> 16#14
 +
</source>
 +
 +
=== setting numeric precision ===
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval '("2 / 3" calc-internal-prec 20))
 +
;; ==> "0.66666666666666666667"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval (quote ("2 / 3" calc-internal-prec 20))))'
 +
# ==> 0.66666666666666666667
 +
</source>
 +
 +
=== setting angular mode ===
 +
 +
<source lang=lisp>
 +
;; emacs lisp
 +
(calc-eval '("arctan2(0, -1)" calc-internal-prec 20 calc-angle-mode rad))
 +
;; ==> "3.1415926535897932385"
 +
</source>
 +
 +
<source lang=bash>
 +
# shell
 +
emacs -Q -batch --eval='(message "%s" (calc-eval (quote ("arctan2(0, -1)" calc-angle-mode rad))))'
 +
# ==> 3.14159265359
 +
</source>

Revision as of 15:54, 21 February 2016

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 example uses message to cause the result to be printed. In -batch mode, message prints to standard output. In emacs lisp, printing is a side effect which only occurs when you ask for it. IELM displays evaluation results as a convenience, and *scratch* only inserts evaluation results 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.

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