![使用 FP 包计算总和中断:FP 错误:UPN 堆栈为空!](https://linux22.com/image/386120/%E4%BD%BF%E7%94%A8%20FP%20%E5%8C%85%E8%AE%A1%E7%AE%97%E6%80%BB%E5%92%8C%E4%B8%AD%E6%96%AD%EF%BC%9AFP%20%E9%94%99%E8%AF%AF%EF%BC%9AUPN%20%E5%A0%86%E6%A0%88%E4%B8%BA%E7%A9%BA%EF%BC%81.png)
我正在尝试汇总表格中的条目,并认为使用fp
包是可行的方法。下面的 MWE,
\AddToTotal{18,000.00}
\AddToTotal{-17,000.00}
\AddToTotal{-8,000.00}
产量:
正如预期的那样。但是,将 -8,000 拆分为两个步骤会破坏以下情况:
\AddToTotal{18,000.00}
\AddToTotal{-17,000.00}
\AddToTotal{-7,000.00}
\AddToTotal{-1,000.00}% <--- Why this break things?
这应该产生相同的结果,但却产生了错误:
FP 错误:UPN 堆栈为空!。\FP@errmessage #1->\errmessage {FP 错误:#1!}
l.25 \AddToTotal{-1,000.00} % <--- 为什么这会破坏事情?
我应该为此使用其他包吗?我只需要 2 位精度,所以也许有更好的选择。
代码:
\documentclass{article}
\usepackage{xstring}
\usepackage{siunitx}
\usepackage{fp}
\newcommand*{\Total}{0.00}% Initial Value
\newcommand*{\AddToTotal}[1]{%
\StrDel{#1}{,}[\NewAmount]%
\FPeval\TempTotal{\Total+\NewAmount}%
\xdef\Total{\TempTotal}%
%% --------
\par
After adding $\NewAmount$, total is \num[round-mode=places,round-precision=2]{\Total}.%
}%
\begin{document}
\AddToTotal{18,000.00}
\AddToTotal{-17,000.00}
\AddToTotal{-7,000.00}
\AddToTotal{-1,000.00}% <--- Why this break things?
\end{document}
答案1
通过在命令中添加额外的括号可以轻松解决此问题\AddToTotal
:
\FPeval\TempTotal{(\Total)+\NewAmount}% <-- extra parentheses around \Total
如果没有括号,负数\Total
将按原样展开,给出类似于-6000+-1000
其中第一个表达式被解释为减法而不是负数的结果。fp
然后产生空栈错误,因为内部堆栈上缺少该减法的第二个操作数。
为了解决这个问题,你必须通过在负数周围放置一对括号来提示它负数是单个原子。现在你正确地得到了:
该替代版本似乎也有效:
\FPeval\TempTotal{0+\Total+\NewAmount}
不确定为什么表达式开始时的解析方式与中间的解析方式不同。
答案2
为什么不直接使用expl3
?无论如何,你都会加载它,因为siunitx
。
\documentclass{article}
\usepackage{siunitx} % also loads xparse and expl3
\sisetup{
round-mode=places,
round-precision=2,
group-separator={,},
group-four-digits,
}
\ExplSyntaxOn
\fp_new:N \g_grill_total_fp % initialized to 0
\tl_new:N \l__grill_total_temp_tl
\NewDocumentCommand{\AddToTotal}{m}
{
\tl_set:Nn \l__grill_total_temp_tl { #1 }
\tl_remove_all:Nn \l__grill_total_temp_tl { , }
\fp_gadd:Nn \g_grill_total_fp { \l__grill_total_temp_tl }
After~adding~\num{\tl_use:N \l__grill_total_temp_tl},~
total~is~\num{\fp_use:N \g_grill_total_fp}.
\par
}
\ExplSyntaxOff
\begin{document}
\AddToTotal{18,000.00}
\AddToTotal{-17,000.00}
\AddToTotal{-7,000.00}
\AddToTotal{-1,000.00}
\end{document}