Ich nutze einen Fortschrittsbalken in Beamer. Bis Folienanzahl 89 funktioniert alles tadellos, ab Folienanzahl 90 kommt die Fehlermeldung.

! Arithmetic overflow. \progressbar@progressbar ...progressbar@tmpcounta \divide \progressbar@tmpdi... l.45 \end{frame}}

\documentclass{beamer}
\usepackage{tikz}
\definecolor{pbbg}{RGB}{0,122,59}% filling color for the progress bar
\definecolor{pbfill}{RGB}{0,122,59}% background color for the progress bar

\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=0.5ex
% the progress bar
\def\progressbar@progressbar{%
    \progressbar@tmpcounta= \insertframenumber % max = ?
    \progressbar@tmpcountb=\inserttotalframenumber      
    \progressbar@tmpdim=.5\progressbar@pbwd
    \multiply\progressbar@tmpdim by \progressbar@tmpcounta
    \divide\progressbar@tmpdim by \progressbar@tmpcountb
    \progressbar@tmpdim=2\progressbar@tmpdim
  \begin{tikzpicture}[rounded corners=1.5pt,very thin]
  \shade[top color=pbbg!20,bottom color=pbbg!20,middle color=pbbg!50]
       (0pt, 0pt) rectangle ++ (\progressbar@pbwd, \progressbar@pbht);

       \shade[draw=pbfill,top color=pbfill!50,bottom color=pbfill!50,middle color=pbfill] %
         (0pt, 0pt) rectangle ++ (\progressbar@tmpdim, \progressbar@pbht);
    \draw[color=normal text.fg!50]
      (0pt, 0pt) rectangle (\progressbar@pbwd, \progressbar@pbht)
        node[pos=0.5,color=normal text.fg] {\textnormal{%
        }%
    };
  \end{tikzpicture}%
}
\addtobeamertemplate{footline}
{%
  \begin{beamercolorbox}[wd=\paperwidth,ht=2.0ex,center,dp=0ex]{white}%
    \progressbar@progressbar%
  \end{beamercolorbox}%
}
\makeatother    
\begin{document}
\foreach \x in {1,2,...,90} {\begin{frame}[label=test]{My frame}
    Test \x
\end{frame}}
\end{document}

gefragt 18 Jul '21, 14:53

Tischa's gravatar image

Tischa
1.4k27102128
Akzeptiert-Rate: 15%

bearbeitet 18 Sep '21, 19:43

Damit, dass es bis 89 funktioniert, meinst du doch die \foreach-schleife, richtig? Ich bekomme da schon ein "Dimension too large" mit \foreach \x in {1,2,...,45}. Ich denke, dass kommt davon, weil beim multiplizieren von der halben papierbreite mit der foliennummer eine zu große länge rauskommt. Ich habe irgendwo gelesen, dass das latex nur ungefähr 2m kann.

Außerdem gibt es aber ganz viele "pdfTeX warning (ext4): destination with the same identifier (name{test<1>}) has been already used, duplicate ignored \relax". Also stimmt noch mehr nicht.

(27 Jul '21, 08:27) huibub

Auch nach der änderung ist die angabe, dass es mit 89 noch funktioniere falsch. Wie man leicht im online compiler feststellen kann, funktioniert es nur bis 44. Hauptgrund ist, dass erst multipliziert und dann dividiert wird. Dabei überschreitet das ergebnis von 2 * (182pt * 45) eben bereits die maximal zulässige Länge von <16384pt. Es nützt leider auch nichts, die division und die multiplikation zu vertauschen, weil \inserttotalframenumber beim ersten latex lauf immer 1 liefert. Mit tex arithmetik ist das so also nicht lösbar. Man müsste schon erst einmal durch einen recht hohen wert teilen.

(20 Sep '21, 09:12) huibub

BTW: Warum verwendest du nicht pgfmath für die berechnung? Das ist doch für berechnungen innerhalb von pgf prädestiniert. Vielleicht kann das (zumindest unter lualatex) auch mit größeren zahlen rechnen. Probiert habe ich es aber nicht.

(20 Sep '21, 09:13) huibub

Wie @huibub bereits in seinen Kommentaren richtig bemerkt hat, darf bei TeX das Ergebnis einer arithmetischen Operation maximal \maxdimen groß sein. \maxdimen ist 16383.99999pt. Dieser Wert wird bei dir bereits auf Frame 45 (und nicht erst auf Frame 90, wie in der Fragestellung behauptet) überschritten. Eine einfache Lösung wäre nun, am Anfang nicht mit der Hälfe der Papierbreite zu rechnen und diese dann am Ende per \progressbar@tempdim=2\progressbar@tempdim wieder auf die ganze Papierbreite zu erhöhen, sondern mit einem wesentlich kleineren Anteil zu arbeiten.

Zusätzlich wäre theoretisch in der Tat zu empfehlen, erst durch die Gesamtzahl der Frames zu dividieren und dann mit der aktuellen Framenummer zu multiplizieren. Leider hat das am Ende dann keine Auswirkungen, weil, wie @huibub ebenfalls in seinen Kommentaren richtig bemerkt, \inserttotalframenumber im ersten LaTeX-Lauf natürlich noch nicht die Gesamtzahl der Frames liefert.

Das Problem mit dem zu kleinen \inserttotalframenumber kann man einfach lösen, indem man testet, ob \inserttotalframenumber größer oder gleich \value{framenumber} ist, was es ja immer sein sollte. Anderenfalls ist die Progressbar ohnehin ungültig und braucht überhaupt nicht mehr (oder alternativ nur mit voller Länge) gezeichnet zu werden. An dieser Stelle sei auch darauf hingewiesen, dass \insertframenumber nicht unbedingt der Weisheit letzter Schluss für die Verwendung in einer Berechnung ist. Ich werde daher stattdessen direkt den Frame-Zähler framenumber verwenden. Kombiniert man das nun mit dem Vertauschen der Operationen ist sichergestellt, dass kein zu großes Zwischen- oder Endergebnis vorkommt und man kann sich die Halbierung aus dem Originalcode sogar ganz sparen.

\documentclass{beamer}
\usepackage{tikz}
\definecolor{pbbg}{RGB}{0,122,59}% filling color for the progress bar
\definecolor{pbfill}{RGB}{0,122,59}% background color for the progress bar

\makeatletter
\def\progressbar@progressbar{} % the progress bar
\newdimen\progressbar@pbht %progressbar height
\newdimen\progressbar@pbwd %progressbar width
\newdimen\progressbar@tmpdim % auxiliary dimension
\progressbar@pbwd=\paperwidth
\progressbar@pbht=0.5ex
% the progress bar
\def\progressbar@progressbar{%
  % Die Progressbar ergibt nur Sinn, wenn \inserttotalframenumber > \value{framenumber} ist
  \expandafter\ifnum \value{framenumber}>\number\inserttotalframenumber\relax\else
    \progressbar@tmpdim=\progressbar@pbwd
    \divide\progressbar@tmpdim by \number\inserttotalframenumber\relax
    \multiply\progressbar@tmpdim by \value{framenumber}
    \begin{tikzpicture}[rounded corners=1.5pt,very thin]
      \shade[top color=pbbg!20,bottom color=pbbg!20,middle color=pbbg!50]
        (0pt, 0pt) rectangle ++ (\progressbar@pbwd, \progressbar@pbht);

      \shade[draw=pbfill,top color=pbfill!50,bottom color=pbfill!50,middle color=pbfill] %
        (0pt, 0pt) rectangle ++ (\progressbar@tmpdim, \progressbar@pbht);
      \draw[color=normal text.fg!50]
        (0pt, 0pt) rectangle (\progressbar@pbwd, \progressbar@pbht)
        node[pos=0.5,color=normal text.fg] {\textnormal{%
        }%
      };
    \end{tikzpicture}%
  \fi
}
\addtobeamertemplate{footline}
{%
  \begin{beamercolorbox}[wd=\paperwidth,ht=2.0ex,center,dp=0ex]{white}%
    \progressbar@progressbar%
  \end{beamercolorbox}%
}
\makeatother    
\begin{document}
\foreach \x in {1,2,...,90} {\begin{frame}[label=test\x]{My frame}
    Test \x
\end{frame}}
\end{document}

Es sei darauf hingewiesen dass es auch einen Nachteil dieser Lösung gibt. Sobald sich die Anzahl der Frames der Breite der Frames in sp annähert, wird die Rechenungenauigkeit von TeX so groß, dass der Fortschrittbalken durch die Rundung zu kurz wird und letztlich auf 0 stehen bleibt. Das dürfte bei Präsentationen aber eine eher theoretische Beschränkung sein, da ich schon Frame-Zahlen im Bereich der in der Frage fälschlich angegebenen Grenze von 90 für eher unüblich hoch halte. Präsentationen mit mehreren tausend Frames dürften in freier Wildbahn kaum vorkommen.

Übrigens ist auch @huibub's Frage berechtigt, warum man die Berechnung nicht gleich mit pgf selbst durchführt. Ich habe nur gerade keine Zeit, mich mit einer entsprechenden Lösung zu beschäftigen.

Mit dem ebenfalls von @huibub gemeldeten Problem der destination with the same identifier habe ich mich ebenfalls befasst. Man kann einfach nicht auf jedem Frame Option label mit demselben Wert verwenden. Das ist schlicht sinnloser Unfug. Der Informationsgehalt ist dann nicht besser als bei Weglassen des Labels. Ich habe stattdessen ein eigentlich ebenfalls sinnloses, eindeutiges Label gesetzt – sinnlos deshalb, weil man eigentlich kein Label mit der Labelnummer im Namen braucht, um die Labelnummer zu bestimmen. :-O

Permanenter link

beantwortet 20 Sep '21, 09:59

gast3's gravatar image

gast3
(ausgesetzt)
Akzeptiert-Rate: 53%

bearbeitet 20 Sep '21, 11:48

Deine Antwort
Vorschau umschalten

Folgen dieser Frage

Per E-Mail:

Wenn sie sich anmelden, kommen Sie für alle Updates hier in Frage

Per RSS:

Antworten

Antworten und Kommentare

Markdown-Grundlagen

  • *kursiv* oder _kursiv_
  • **Fett** oder __Fett__
  • Link:[Text](http://url.com/ "Titel")
  • Bild?![alt Text](/path/img.jpg "Titel")
  • nummerierte Liste: 1. Foo 2. Bar
  • zum Hinzufügen ein Zeilenumbruchs fügen Sie einfach zwei Leerzeichen an die Stelle an der die neue Linie sein soll.
  • grundlegende HTML-Tags werden ebenfalls unterstützt

Frage-Themen:

×138
×2
×2

gestellte Frage: 18 Jul '21, 14:53

Frage wurde gesehen: 2,718 Mal

zuletzt geändert: 20 Sep '21, 18:09