6

This simple code produces

"Missing number, treated as zero"

\documentclass{article}
\newcounter{test}
\newcounter{testtwo}
\usepackage{calc}
\usepackage{amsmath}
\begin{document}
 \addtocounter{test}{\value{testtwo}*\value{testtwo}}
\end{document}

In the following situations compiles good:

  • Without amsmath
  • When calc is loaded after amsmath
  • using \setcounter instead of \addtocounter

What is happening here?

If a class loads calc and we need amsmath, what can we do? I know that a solution in this case would be loading amsmath before the class with \RequirePackage. It is possible another workaround between both \usepackage?

4
  • calc does some redefinitions in the addtocounter macro. Standard addtocounter strips down to a TeX advance which does not work with three tokens (value1 * value2).
    – user31729
    Apr 18 '15 at 5:27
  • @ChristianHupfer Hi, happy to see your real name again! Apr 18 '15 at 5:37
  • @karlkoeller: Yes, I am on the Dark Side again ;-) Thanks
    – user31729
    Apr 18 '15 at 5:41
  • Thanks. Both worked and was what I want. As a side question: loading calc after amsmath works as a "fix", but it breaks some functionality of amsmath for which its developers defined these macros in that way? Apr 18 '15 at 15:36
6

A quicker workaround, regardless which package is loaded first, is to use \numexpr from e-tex extensions (which should be available for basically any TeX distribution nowadays).

It expands the values of the calculation before it's advance by \addtocounter

In the following MWE the result is, as expected, 100

\documentclass{article}
\newcounter{test}
\newcounter{testtwo}
\usepackage{calc}
\usepackage{amsmath}
\begin{document}
\setcounter{testtwo}{10}

\addtocounter{test}{\numexpr\value{testtwo}*\value{testtwo}}

\thetest
\end{document}
2
  • If you use \numexpr then you don't need calc... Apr 18 '15 at 6:17
  • @karlkoeller: Right. I kept it in order to prove that it works this way (regarding the loading order)
    – user31729
    Apr 18 '15 at 6:21
5

Since calc redefines \setcounter, \stepcounter and \addtocounter, the only way you have if you want to keep your settings is to redeclare these definitions after loading amsmath.

That is, add the following lines in your preamble after \usepackage{amsmath}

\makeatletter
\def\setcounter#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}%
   {\calc@assign@count{\global\csname c@#1\endcsname}{#2}}}
  \def\addtocounter#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}%
    {\calc@assign@count{\global\advance\csname c@#1\endcsname}{#2}}}%
  \def\stepcounter#1{\@ifundefined {c@#1}%
    {\@nocounterr {#1}}%
    {\global\advance\csname c@#1\endcsname \@ne
    \begingroup
      \let\@elt\@stpelt \csname cl@#1\endcsname
    \endgroup}}%
\@ifpackageloaded{amstext}{%
 \expandafter\def\expandafter\stepcounter
    \expandafter#\expandafter1\expandafter{%
    \expandafter\iffirstchoice@\stepcounter{#1}\fi
 }
 \expandafter\def\expandafter\addtocounter
    \expandafter#\expandafter1\expandafter#\expandafter2\expandafter{%
    \expandafter\iffirstchoice@\addtocounter{#1}{#2}\fi
 }
}{}
\makeatother

MWE:

\documentclass{article}
\newcounter{test}
\newcounter{testtwo}
\usepackage{calc}
\usepackage{amsmath}
\makeatletter
\def\setcounter#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}%
   {\calc@assign@count{\global\csname c@#1\endcsname}{#2}}}
  \def\addtocounter#1#2{\@ifundefined{c@#1}{\@nocounterr{#1}}%
    {\calc@assign@count{\global\advance\csname c@#1\endcsname}{#2}}}%
  \def\stepcounter#1{\@ifundefined {c@#1}%
    {\@nocounterr {#1}}%
    {\global\advance\csname c@#1\endcsname \@ne
    \begingroup
      \let\@elt\@stpelt \csname cl@#1\endcsname
    \endgroup}}%
\@ifpackageloaded{amstext}{%
 \expandafter\def\expandafter\stepcounter
    \expandafter#\expandafter1\expandafter{%
    \expandafter\iffirstchoice@\stepcounter{#1}\fi
 }
 \expandafter\def\expandafter\addtocounter
    \expandafter#\expandafter1\expandafter#\expandafter2\expandafter{%
    \expandafter\iffirstchoice@\addtocounter{#1}{#2}\fi
 }
}{}
\makeatother
\begin{document}
 \setcounter{testtwo}{6}
 \addtocounter{test}{\value{testtwo}*\value{testtwo}}
 \the\value{test}
\end{document}

Output

enter image description here

1
  • Very elaborate! I was too lazy to copy all the stuff to the MWE ;-)
    – user31729
    Apr 18 '15 at 5:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.