注意:这个问题与这个,但由于我使用的是浮点值而不是整数,因此有所不同。
我正在使用 Python 脚本自动生成 LaTeX 表,其中包含十进制小时形式的时间,这些时间始终是 15 分钟的倍数,因此可能的值为 0.25、0.50、0.75、1.00、1.25,...
在 LaTeX 中,我想自动计算这些值的总和。在生成文件的脚本中计算总和很容易,但即使手动编辑文本,总和也必须正确。
目前有效的方法如下:
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{tabularx}
\usepackage{pgf}
\usepackage{pgfplots}
\pgfkeys{/pgf/fpu}
\pgfkeys{
/pgf/number format/precision=2,
/pgf/number format/fixed=true,
/pgf/number format/fixed zerofill=true,
/pgf/number format/assume math mode=true,
/pgf/number format/use comma=true
}
\newcommand{\minutestohours}[1]{
\pgfmathparse{#1/60}\pgfmathprintnumber{\pgfmathresult}
}
\newcounter{totalminutes}
\newcommand{\addtime}[1]{
\addtocounter{totalminutes}{#1}
\minutestohours{#1}
}
\begin{document}
\begin{tabularx}{.5\textwidth}{XX}
1 & \addtime{60} \\ \hline
2 & \addtime{90} \\ \hline
3 & \addtime{195} \\ \hline
4 & \addtime{255} \\ \hline
5 & \addtime{45} \\ \hline
6 & \addtime{180} \\ \hline
7 & \addtime{105} \\ \hline
8 & \addtime{30} \\ \hline
9 & \addtime{240} \\ \hline
10 & \addtime{30} \\ \hline
11 & \addtime{195} \\ \hline
12 & \addtime{90} \\ \hline
13 & \addtime{225} \\ \hline
\end{tabularx}
\vspace*{5mm}
Sum: \minutestohours{\thetotalminutes}
\end{document}
这将生成一个如下所示的文档,这是所需的结果:
请注意,总和的正确值为 29。问题在于我不想以分钟的形式输入时间,而是以打印的十进制小时形式输入时间。我尝试使用 计算分钟并将pgfmath
结果存储在计数器中totalminutes
,该计数器可在以下代码片段中找到,但最终结果将为 0.22(即 13/60)。
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{tabularx}
\usepackage{pgf}
\usepackage{pgfplots}
\pgfkeys{/pgf/fpu}
\pgfkeys{
/pgf/number format/precision=2,
/pgf/number format/fixed=true,
/pgf/number format/fixed zerofill=true,
/pgf/number format/assume math mode=true,
/pgf/number format/use comma=true
}
\newcommand{\minutestohours}[1]{
\pgfmathparse{#1/60}\pgfmathprintnumber{\pgfmathresult}
}
\newcounter{totalminutes}
\newcommand{\addtime}[1]{
\pgfmathparse{#1}
\pgfmathprintnumber{\pgfmathresult}
\pgfmathparse{int(#1*60)}
\pgfmathtruncatemacro{\minutes}{\pgfmathresult}
\addtocounter{totalminutes}{\minutes}
}
\begin{document}
\begin{tabularx}{.5\textwidth}{XX}
1 & \addtime{1.00} \\ \hline
2 & \addtime{1.50} \\ \hline
3 & \addtime{3.25} \\ \hline
4 & \addtime{4.25} \\ \hline
5 & \addtime{0.75} \\ \hline
6 & \addtime{3.00} \\ \hline
7 & \addtime{1.75} \\ \hline
8 & \addtime{0.50} \\ \hline
9 & \addtime{4.00} \\ \hline
10 & \addtime{0.50} \\ \hline
11 & \addtime{3.25} \\ \hline
12 & \addtime{1.50} \\ \hline
13 & \addtime{3.75} \\ \hline
\end{tabularx}
\vspace*{5mm}
Sum: \minutestohours{\thetotalminutes}
\end{document}
我也尝试过根本不使用计数器,而是直接通过存储结果(pgfmath
如下面的代码片段所示),但这将产生总和 87(即 29*3)。
\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[ngerman]{babel}
\usepackage{tabularx}
\usepackage{pgf}
\usepackage{pgfplots}
\pgfkeys{/pgf/fpu}
\pgfkeys{
/pgf/number format/precision=2,
/pgf/number format/fixed=true,
/pgf/number format/fixed zerofill=true,
/pgf/number format/assume math mode=true,
/pgf/number format/use comma=true
}
\newcommand{\minutestohours}[1]{
\pgfmathparse{#1/60}\pgfmathprintnumber{\pgfmathresult}
}
\pgfmathsetmacro{\totalminutes}{0}
\newcommand{\addtime}[1]{
\pgfmathparse{#1}
\pgfmathprintnumber{\pgfmathresult}
\pgfmathparse{\totalminutes+int(#1*60)}
\pgfmathsetmacro{\totalminutes}{\pgfmathresult}
\xdef\totalminutes{\totalminutes}
}
\begin{document}
\begin{tabularx}{.5\textwidth}{XX}
1 & \addtime{1.00} \\ \hline
2 & \addtime{1.50} \\ \hline
3 & \addtime{3.25} \\ \hline
4 & \addtime{4.25} \\ \hline
5 & \addtime{0.75} \\ \hline
6 & \addtime{3.00} \\ \hline
7 & \addtime{1.75} \\ \hline
8 & \addtime{0.50} \\ \hline
9 & \addtime{4.00} \\ \hline
10 & \addtime{0.50} \\ \hline
11 & \addtime{3.25} \\ \hline
12 & \addtime{1.50} \\ \hline
13 & \addtime{3.75} \\ \hline
\end{tabularx}
\vspace*{5mm}
Sum: \minutestohours{\totalminutes}
\end{document}
那么,我该如何定义\addtime
才能使最终结果正确呢?运行总和是以分钟(int)还是小时(float)存储并不重要,只要输入\addtime
是以小时为单位即可。
答案1
下面使用一些包来为此提供自动化解决方案。
包collcell
用于收集数字、xfp
对数字求和、siunitx
输出数字,以及array
将各个部分粘贴在一起。
结果是特殊的“列”规范\summed
。它接受一个可选参数(输出选项siunitx
)和两个强制参数(存储总和的宏名称和要使用的实际列类型)。
\documentclass[]{article}
\usepackage{array}
\usepackage{collcell}
\usepackage{tabularx}
\usepackage{xfp}
\usepackage[output-decimal-marker={,}]{siunitx}
\makeatletter
\newcolumntype\summed{}
\expandafter\renewcommand\expandafter*\csname NC@rewrite@\string\summed\endcsname[3][]
{%
\gdef#2{0}%
\@temptokena\expandafter
{%
\the\@temptokena
>{\collectcell{\summed@col#2{#1}}}#3<{\endcollectcell}%
}%
\NC@find
}
\newcommand*\summed@col[3]{\xdef#1{\fpeval{#1+#3}}\tablenum[{#2}]{#3}}
\makeatother
\begin{document}
\begin{tabularx}{.5\textwidth}{X\summed[table-format=1.2]\mysum{X}}
1 & 1.00 \\ \hline
2 & 1.50 \\ \hline
3 & 3.25 \\ \hline
4 & 4.25 \\ \hline
5 & 0.75 \\ \hline
6 & 3.00 \\ \hline
7 & 1.75 \\ \hline
8 & 0.50 \\ \hline
9 & 4.00 \\ \hline
10 & 0.50 \\ \hline
11 & 3.25 \\ \hline
12 & 1.50 \\ \hline
13 & 3.75 \\ \hline
\end{tabularx}
\bigskip
Sum: \mysum
\end{document}