对 tabularx 中的浮点值进行求和

对 tabularx 中的浮点值进行求和

注意:这个问题与这个,但由于我使用的是浮点值而不是整数,因此有所不同。

我正在使用 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}

在此处输入图片描述

相关内容