使用 \def 和 \ifnum 条件时的微妙之处

使用 \def 和 \ifnum 条件时的微妙之处

我在比较使用 传递的两个数字时遇到了一些困难 \ifnum。考虑命令

\def\comparenum[#1,#2]
{
  \def\x{#1}
  \def\y{#2}
  \ifnum\x=\y
   TRUE
  \else
   FALSE
  \fi
}

\comparenum[1,1]TRUE就像我预期的那样。但是,如果我将上面的内容替换为

\ifnum\x=\y
  1
\else
  0
\fi

相同的调用\comparenum[1,1]会产生0(替换\y\y{},或者确实#2似乎可以解决这个问题)。这种行为的原因是什么?我想使用第二种构造,这样我就可以像上面的答案一样将语句嵌套在另一个条件中如何在 TeX 中形成“如果...或...那么”条件?

答案1

你的第二个代码相当于

\def\comparenum[#1,#2]{ \def\x{#1} \def\y{#1} \ifnum\x=\y1 \else0 \fi}

(因为控制字后空格和行尾会被忽略)。现在您应该能够看到代码的主要问题。当 TeX 评估条件时,它需要两个数字并进行完全扩展,直到找到不能解释为数字的标记。

因此,它会扩展\x=停止搜索数字,同时开始查找下一个数字;它\y会扩展并1跟进。因此,该调用\comparenum[1,1]将转换为

\ifnum1=11 \else0 \fi

这当然会返回 false。

你可以解决这个问题

\def\comparenum[#1,#2]{%
  \def\x{#1}%
  \def\y{#1}%
  \ifnum\x=\y\relax
    1% 
  \else
    0%
  \fi
}

\relax令牌停止数字查找。

另一方面,此构造不可扩展。您可以使用以下方法制作可扩展版本

\def\comparenum[#1,#2]{%
  \ifnum#1=#2\space
    1%
  \else
    0%
  \fi
}

扩展\space为空格标记,停止\ifnum查找更多数字,然后被规则忽略。但是,如果与计数器寄存器一起使用,则会留下一个空格。更安全的版本是

\def\comparenum[#1,#2]{%
  \ifnum#1=\expandafter\id\expandafter{\number#2}\space
    1%
  \else
    0%
  \fi
}
\def\id#1{#1}

e-TeX 版本会更简单:

\def\comparenum[#1,#2]{%
  \ifnum#1=\numexpr#2\relax
    1%
  \else
    0%
  \fi
}

请注意%保护行尾,避免在输出中产生空格。

相关内容