Calculating the value of a formula without duplication, using LuaTeX or similar
As the two nice answers of @marmot and @Mico did not at all address the main query (to code only once and get both the typesetting and the value) (see the answer by @JosephWright), I feel at liberty to add one more answer not addressing the request, but doing the computation with xfp
.
(but see update at bottom for a \printandeval
)
\documentclass{article}
\usepackage[fleqn]{amsmath}
\usepackage{xfp}
\usepackage{siunitx}
\begin{document}
\begin{equation*}
N = \frac{19.32\times1\times10^6\times6.023\times10^{23}}{197}
=\num[scientific-notation=true,
round-mode=figures,
round-precision=4]{\fpeval{19.32*1*10^6*6.023*10^23/197}}
\end{equation*}
\end{document}
I did not know how to instruct \fpeval
to output in scientific notation (with a given number of places), but the options of \num
came to the rescue.
I will also mention xintexpr
(as I authored it) despite the fact that I still have to add math functions to it (only sqrt
currently is available). Now, its syntax \xintthefloatexpr...\relax
causes issues with the way the siunitx
\num
parses its argument. One did not get into such problem with \fpeval
because \fpeval
uses braces. So let's just add one user interface macro to use braces too, and this makes \num
happy.
\documentclass{article}
\usepackage[fleqn]{amsmath}
\usepackage{xintexpr}
% make \num of siunitx happy, let xintexpr do the rounding to 4 digits
% of float precision (after having computed with 16 digits of
% precision, per default)
% #1 = final precision for printing, #2 = expression to evaluate
\newcommand\floatround[2]{\xintthefloatexpr [#1]#2\relax}
\usepackage{siunitx}
\begin{document}
\begin{equation*}
N = \frac{19.32\times1\times10^6\times6.023\times10^{23}}{197}
=\num{\floatround{4}{19.32*1*10^6*6.023*10^23/197}}
% one can also use ** in place of ^ for powers
\end{equation*}
\end{document}
Finally package numprint
has much to recommend to print numbers according to language of document. And its \numprint
macro (or \np
with package option np
) will accept directly the \xintthefloatexpr
with no hiding within braces contrarily to \num
of siunitx.
\documentclass[english]{article}
\usepackage{babel}
\usepackage[fleqn]{amsmath}
\usepackage{xintexpr}
\usepackage[np, autolanguage]{numprint}
\begin{document}
\begin{equation*}
N = \frac{19.32\times1\times10^6\times6.023\times10^{23}}{197}
=\np{\xintthefloatexpr [4] 19.32*1*10^6*6.023*10^23/197\relax}
\end{equation*}
\end{document}
In the simple example considered here one can do like this:
\documentclass[english]{article}
\usepackage{babel}
\usepackage[fleqn]{amsmath}
\usepackage{xintexpr}
\usepackage[np, autolanguage]{numprint}
\newcommand\printandeval[1]{#1=\begingroup
\def\frac##1##2{(##1)/(##2)}%
\def\times{*}%
% etc...
\edef\x{{\xintthefloatexpr[4]#1\relax}}%
\expandafter\endgroup\expandafter\np\x
}
% (in the above we need to re-enact standard meaning of things
% such as \times, before \np does the typesetting of the value,
% this is the reason for the `\expandafter` chain.
\begin{document}
\begin{equation*}
N = \printandeval{\frac{19.32\times1\times10^6\times6.023\times10^{23}}{197}}
\end{equation*}
\end{document}
I do not try here to provide a completely general one, but in pratice adding a few more redefinitions will cover many test cases, possibly enough for real life usage.
notice that braces in the input for typesetting did not have to be replaced by parentheses before evaluation (cf 10^{23}
)
Here is with xfp
+ siunitx
:
\documentclass{article}
\usepackage[fleqn]{amsmath}
\usepackage{xfp}
\usepackage{siunitx}
\newcommand\printandeval[1]{#1=\begingroup
\def\frac##1##2{(##1)/(##2)}%
\def\times{*}%
% etc...
\edef\x{[scientific-notation=true,
round-mode=figures,
round-precision=4]{\fpeval{#1}}}%
\expandafter\endgroup\expandafter\num\x
}
\begin{document}
\begin{equation*}
N = \printandeval{\frac{19.32\times1\times10^6\times6.023\times10^{23}}{197}}
\end{equation*}
\end{document}
Same output.
The code above can be slightly more efficient with
\edef\x{\endgroup\noexpand\np{\xintthefloatexpr[4]#1\relax}}%
\x
in the numprint+xintexpr
case and
\edef\x{\endgroup\num[scientific-notation=true,
round-mode=figures,
round-precision=4]{\fpeval{#1}}}%
\x
in the siunitx+xfp
case.
thanks to @egreg for chasing \expandafter
's and pointing out \num
is \protected
and giving me opportunity in this edit to discover new ways to mark-up multi-line code... (I am too much active on github)
As long as the expression is not too complex, we can use the LaTeX3 FPU to do the work here. I've gone for an approach where the input is 're-written' into the appropriate syntax: one could do that for the Lua-based answers given by others, too.
\documentclass{article}
\usepackage{siunitx,xparse}
\ExplSyntaxOn
\NewDocumentCommand { \printandcalc } { m }
{
#1 =
\group_begin:
\tl_set:Nn \l_tmpa_tl {#1}
\cs_set:Npn \frac ##1##2 {##1/(##2)}
\cs_set:Npn \times { * }
\cs_set:Npx \__cs_tmp:w ##1 { \token_to_str:N ^ (##1) }
\char_set_active_eq:NN ^ \__cs_tmp:w
\tl_set_rescan:Nnx \l_tmpa_tl { \char_set_catcode_active:n { `\^ } }
{ \l_tmpa_tl }
\tl_set:Nx \l_tmpa_tl { \l_tmpa_tl }
\exp_args:NNNV \group_end:
\tl_set:Nn \l_tmpa_tl \l_tmpa_tl
\num [scientific-notation = true, round-mode = places]
{ \fp_eval:n { \l_tmpa_tl } }
}
\begin{document}
\[
N = \printandcalc{\frac{19.32\times1\times10^6\times6.023\times10^{23}}{197}}
\]
\end{document}
Welcome to TeX.SE! There is whole discussion on doing serious computations in LaTeX. My answer is based on this answer and at best a starting point, which shows that it is indeed possible to do something along those lines.
\documentclass{article}
\usepackage[fleqn]{amsmath}
\usepackage{luacode}
% from https://tex.stackexchange.com/a/294465/121799
\def\luaprint#1{\directlua{tex.print(#1)}}
\begin{document}
\begin{equation*}
N = \frac{6.022\cdot10^{23}}{1.2\cdot10^{19}}
=\luaprint{(1.932*10^6)*6.022*10^(23)/(197)}
\end{equation*}
\end{document}
Notice also that there are various possibilities to print these numbers in LateX. Unfortunately, I do not know too much on luacode
but what I do know is that section 92 of the pgfmanual lists several possibilities to do that in TikZ/pgf.