TeX - LaTeX Asked on February 20, 2021
I am trying to implement a progress bar into my beamer theme, but as soon as I hit 45 frames, I get the error message
! Arithmetic overflow.
progressbar@progressbar ...progressbar@tmpcounta
divide progressbar@tmpdi...
Here is my MWE:
documentclass{beamer}
usepackage{tikz}
makeatletter
defprogressbar@progressbar{} % the progress bar
newcountprogressbar@tmpcounta% auxiliary counter
newcountprogressbar@tmpcountb% auxiliary counter
newdimenprogressbar@pbht %progressbar height
newdimenprogressbar@pbwd %progressbar width
newdimenprogressbar@tmpdim % auxiliary dimension
progressbar@pbwd=paperwidth
progressbar@pbht=1cm
% the progress bar
defprogressbar@progressbar{%
progressbar@tmpcounta=insertframenumber
progressbar@tmpcountb=inserttotalframenumber
progressbar@tmpdim=progressbar@pbwd
multiplyprogressbar@tmpdim by progressbar@tmpcounta
divideprogressbar@tmpdim by progressbar@tmpcountb
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}
What is the reason behind and how can I avoid it?
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
,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
defprogressbar@progressbar{} % the progress bar
newcountprogressbar@tmpcounta% auxiliary counter
newcountprogressbar@tmpcountb% auxiliary counter
newdimenprogressbar@pbht %progressbar height
newdimenprogressbar@pbwd %progressbar width
newdimenprogressbar@tmpdim % auxiliary dimension
progressbar@pbwd=paperwidth
progressbar@pbht=1cm
% the progress bar
defprogressbar@progressbar{%
progressbar@tmpcounta=insertframenumber
progressbar@tmpcountb=inserttotalframenumber
progressbar@tmpdim=progressbar@pbwd
% to show current values
rlap{theprogressbar@tmpdim, theprogressbar@tmpcounta}%
pgfmathparse{progressbar@tmpcounta/progressbar@tmpcountb}%
progressbar@tmpdim=pgfmathresultprogressbar@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}
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
newdimenprogressbar@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}
Correct answer by muzimuzhi Z on February 20, 2021
A more simplified approach that I am now using might be a bit easier to read, but of course not as flexible as before, but it makes use of the fact that for PGF you don't need to convert the macros to counters before, hence this works to produce a progress bar that is variable in height and is inverted. It also takes into account muzimuzhi's comment regarding the use of pgfmathsetmacro
:
documentclass{beamer}
usepackage{tikz}
makeatletter
newdimenprogressbar@height
newcountprogressbar@progress
progressbar@height=1cm
addtobeamertemplate{footline}{}{%
begin{tikzpicture}
useasboundingbox (0pt, 0pt) rectangle ++ (paperwidth, progressbar@height);
begin{scope}
pgfmathsetmacroprogressbar@progress{insertframenumber/inserttotalframenumber}
clip (progressbar@progress * paperwidth, 0pt) rectangle (paperwidth, progressbar@height);
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}%
}
makeatother
begin{document}
foreach x in {1,2,...,50} {begin{frame}{My frame}
Test x
end{frame}}
end{document}
Answered by TobiBS on February 20, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP