5

I would like to know how to check properly for evenness or oddness within some macro. I have played a little with fp and pgfmath package, but it seems I am not keen enough in TeX to do it properly. Here is a sample example where I try to check evenness of 2 parameters:

\documentclass{article}
\usepackage{tikz}

\def\IfEven#1{\pgfmathparse{int(mod(#1,2))}\ifnum\pgfmathresult=0}
\newcommand{\parity}[2]{%                                                                             
  \def\x{#1}%                                                                                         
  \def\y{#2}%                                                                                         
  \IfEven{\x}%                                                                                        
    \IfEven{\y}%                                                                                        
      {\x} and {\y} are even.%                                                                            
    \else%                                                                                              
      {\x} is even and {\y} is odd.%                                                                      
    \fi%                                                                                                
  \else%                                                                                              
    \IfEven{\y}%                                                                                        
      {\x} is odd and {\y} is even.%                                                                      
    \else%                                                                                              
      {\x} and {\y} are odd.%                                                                             
    \fi%                                                                                                
  %% If I put a second \fi here I got an error 'Extra \fi.', otherwise                                
  %% it compiles and works fine but there are two warnings:                                           
  %% (\end occurred when \ifnum on line 28 was incomplete)                                            
  %% (\end occurred when \ifnum on line 26 was incomplete)                                            
}

\begin{document}
\parity{0}{7}\\
\parity{3}{3}\\
\parity{2}{6}\\
\parity{1}{4}\\
\end{document}

I do understand that I should write a second \fi (but it does not compile). Otherwise, it compiles, displays what I was expecting, but I do not feel comfortable at all with the warnings... and I guess the more I will be using this macro, the more I will have warnings.

So If you have any suggestions...

2 Answers2

3

don't do

\def\IfEven#1{\pgfmathparse{int(mod(#1,2))}\ifnum\pgfmathresult=0}

as such a syntax leaves trailing \else and \fi not matched by a tex-primitive \if.

Either use \if syntax or use argument syntax

\pgfmathparse{int(mod(#1,2))}%
\ifnum\pgfmathresult=0
yes
\else
no
\fi

or

\def\IfEven#1#2#3{\pgfmathparse{int(mod(#1,2))}\ifnum\pgfmathresult=0 %need this space!
 #2%
 \else
 #3%
 \fi}

then

\IfEven{\x}{yes}{no}
David Carlisle
  • 757,742
2

When conditional text is skipped over, TeX still keeps track of \if..., \else and \fi.

When you call \parity{1}{0}, the first \IfEven is expanded, leaving \ifnum in the input stream. Since the conditional returns false, the inner \IfEven is not expanded and the first \else is matched to \ifnum.

There is an old trick for this, using \if. The trick is ascribed to the Grand Wizard himself.

\documentclass{article}
\usepackage{tikz}

\def\IsEven#1{%
  TT\fi
  \pgfmathparse{int(mod(#1,2))}%
  \ifnum\pgfmathresult=0
}
\newcommand{\parity}[2]{%
  \if\IsEven{#1}%
    \if\IsEven{#2}%
      #1 and #2 are even.%
    \else%
      #1 is even and #2 is odd.%
    \fi
  \else
    \if\IsEven{#2}%
      #1 is odd and #2 is even.%
    \else
      #1 and #2 are odd.%
    \fi
  \fi
}

\begin{document}

\parity{0}{7}

\parity{3}{3}

\parity{2}{6}

\parity{1}{4}

\end{document}

This way there is always a conditional to make the correct balance. When it is in non-skipped over text, \if triggers expansion of \IsEven which will leave

\if TT\fi
<code>
\ifnum...

and the conditionals will be balanced again. The \if TT\fi part expands to nothing.

enter image description here

egreg
  • 1,121,712