答案1
由于@marmot 和@Mico 的两个很好的答案根本没有解决主要查询(只编码一次并获取排版和值)(参见@JosephWright 的回答),我可以自由地添加一个答案,不是解决请求,而是用进行计算xfp
。
(但请参阅底部的更新\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}
我不知道如何指示\fpeval
以科学计数法(给定位数)输出,但是选项\num
可以帮上忙。
我还会提到xintexpr
(因为我是它的作者),尽管我仍然需要向其中添加数学函数(sqrt
目前只有可用)。现在,它的语法会导致解析其参数\xintthefloatexpr...\relax
的方式出现问题。因为使用括号,所以siunitx
\num
没有遇到这样的问题。所以让我们添加一个用户界面宏来使用括号,这很开心。\fpeval
\fpeval
\num
\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}
最后打包numprint
有很多建议根据文档语言打印数字。并且其\numprint
宏(或\np
与包选项一起np
)将直接接受\xintthefloatexpr
括号内的内容,而与\num
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}
在这里考虑的简单示例中,可以这样做:
\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}
我并不试图在这里提供一个完全通用的定义,但在实践中,添加一些重新定义将涵盖许多测试用例,可能足以满足实际使用。
请注意,排版输入中的括号在评估之前不必用圆括号替换(参见10^{23}
)
以下是带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}
相同的输出。
上面的代码可以稍微提高效率
\edef\x{\endgroup\noexpand\np{\xintthefloatexpr[4]#1\relax}}% \x
在这种numprint+xintexpr
情况下
\edef\x{\endgroup\num[scientific-notation=true, round-mode=figures, round-precision=4]{\fpeval{#1}}}% \x
在这种siunitx+xfp
情况下。
感谢 @egreg 追踪\expandafter
并指出,\num
并\protected
让我有机会在这次编辑中发现标记多行代码的新方法......(我在 github 上太活跃了)
答案2
只要表达式不是太复杂,我们就可以使用 LaTeX3 FPU 来完成这项工作。我采用了一种方法,将输入“重写”为适当的语法:也可以对其他人给出的基于 Lua 的答案这样做。
\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}
答案3
欢迎来到 TeX.SE!这里有关于如何LaTeX 中的严肃计算。我的回答基于这个答案最好是一个起点,表明确实有可能按照这样的思路做某事。
\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}
还要注意,在 LateX 中有多种打印这些数字的可能性。不幸的是,我对此了解不多,luacode
但我知道的是 pgfmanual 的第 92 节列出了在 Ti 中执行此操作的几种可能性钾Z/pgf。
答案4
这个答案仅仅是@marmot 的回答。它使用(a)环境luacode
以允许使用“魔法”字符的方式定义 Lua 函数%
,以及(b)包\num
的宏siunitx
,以美化 Lua 计算的输出。
这绝对是可能的创建一个预处理器类型的函数,用于捕获和修改\frac{...}{...}
、\log
、\sin
、\pi
等的所有实例,以便 Lua 可以解析代码。(它必须处于预处理器阶段,这样 TeX 才不会尝试对\frac
、^
等进行操作。)一个非常重要的考虑因素是 TeX 的分组字符{
和}
必须替换为(
和)
。除非您需要在文档中执行大量公式评估,否则“手动”执行简化和调整几乎肯定会快得多。
\documentclass{article}
\usepackage{luacode,siunitx}
%% Lua-side code:
\begin{luacode}
function luaprint ( n )
return tex.sprint ( string.format ( "%.3e" , n ) )
end
\end{luacode}
%% LaTeX-side code:
\def\luaprint#1{\num{\directlua{luaprint(#1)}}}
\begin{document}
\[
N = \frac{19.32\times1\times10^6\times6.023\times10^{23}}{197}
=\luaprint{(19.32*1*10^6*6.023*10^(23))/197}
\]
\end{document}