Why is there an arithmetic overflow in the progress bar with more than 44 frames?
TeX has a \maxdimen
(16383.99999pt
), which represents the largest dimension you can use in an dimension expression. See discussions among \maxdimen
on this site, including my answer.
When \x == 45
,
\progressbar@tmpdim == 364.19536pt
and\progressbar@tmpcounta == 45
,- their multiplication
364.19536pt * 45 = 16,388.7912pt
, is slightly larger than\maxdimen
, hence raises "arithmetic overflow" and the result of multiplication is truncated.
Since the final result @tmpdim * @tmpcounta / @tmpcountb
is smaller than \maxdimen
, we can firstly compute @tmpcounta / @tmpcountb
, then compute @tmpdim * <ratio>
. Here is a try making use of \pgfmathparse
from pgfmath
, which is an autoloaded sub-package of tikz
:
\documentclass{beamer}
\usepackage{tikz}
\makeatletter
\def\progressbar@progressbar{} % the progress bar
\newcount\progressbar@tmpcounta% auxiliary counter
\newcount\progressbar@tmpcountb% auxiliary counter
\newdimen\progressbar@pbht %progressbar height
\newdimen\progressbar@pbwd %progressbar width
\newdimen\progressbar@tmpdim % auxiliary dimension
\progressbar@pbwd=\paperwidth
\progressbar@pbht=1cm
% the progress bar
\def\progressbar@progressbar{%
\progressbar@tmpcounta=\insertframenumber
\progressbar@tmpcountb=\inserttotalframenumber
\progressbar@tmpdim=\progressbar@pbwd
% to show current values
\rlap{\the\progressbar@tmpdim, \the\progressbar@tmpcounta}%
\pgfmathparse{\progressbar@tmpcounta/\progressbar@tmpcountb}%
\progressbar@tmpdim=\pgfmathresult\progressbar@tmpdim
\begin{tikzpicture}
\useasboundingbox (0pt, 0pt) rectangle ++ (\progressbar@pbwd, \progressbar@pbht);
\begin{scope}
\clip (\progressbar@tmpdim, 0pt) rectangle (\progressbar@pbwd, \progressbar@pbht);
\node[anchor=south west,inner sep=0pt,outer sep=0pt,minimum height=1cm,minimum width=\paperwidth,fill=green] at (0pt,0pt) {};
\end{scope}
\end{tikzpicture}%
}
\addtobeamertemplate{footline}{}{\vspace*{-1cm}\progressbar@progressbar}
\makeatother
\begin{document}
\foreach \x in {1,2,...,45} {\begin{frame}[label=test]{My frame}
Test \x
\end{frame}}
\end{document}
Update
Sorry, I paid too much attention to the error message "arithmetic overflow" yesterday, but not the whole picture of drawing a progress bar. Inspired by @TobiBS's answer, I find the implementation can be further simplified to
\documentclass{beamer}
\usepackage{tikz}
\makeatletter
\newdimen\progressbar@height
\progressbar@height=1cm
\addtobeamertemplate{footline}{}{%
\begin{tikzpicture}
\useasboundingbox (0pt, 0pt) rectangle (\paperwidth, \progressbar@height);
% you can use pgfmath expressions directly in coordinate specifications
\fill[green] (\insertframenumber/\inserttotalframenumber*\paperwidth, 0)
rectangle (\paperwidth, \progressbar@height);
\end{tikzpicture}%
}
\makeatother
\begin{document}
\foreach \x in {1,2,...,50} {
\begin{frame}{My frame}
Test \x
\end{frame}
}
\end{document}