嵌套 FPifeq :额外的 \fi 错误

嵌套 FPifeq :额外的 \fi 错误

我想要一个带有 1 个参数的命令单元并返回:

  • 如果参数为 1,则不执行任何操作
  • -如果参数为 -1
  • 任何其他情况下的参数

目标是展示X和 -X而不是我随机生成的练习中的 1*x* 和 -1*x*。

这是我发出的命令:

\newcommand\Unit[1]{\FPifeq#1{1}{}\else\FPifeq#1{-1}{-}\else#1\fi\fi}

但是,它会产生以下错误

Extra \fi

最小示例:

\documentclass[a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{geometry}
\geometry{hmargin=1cm,vmargin=1cm}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{fp}


\begin{document}

\newcommand\Unit[1]{\FPifeq#1{1}{}\else\FPifeq#1{-1}{-}\else#1\fi\fi}

\Unit{2}x \Unit{1}x \Unit{-1}x


\end{document}

答案1

\FPifeq不喜欢嵌套在条件中,因为它不是条件句。其结构基本上是

  • 进行一些比较,最终有助于决定是否执行\FP@testtrue\FP@testfalse,使其\ifFP@test等于\iftrue\iffalse
  • 设为\ifFPtest等于\ifFP@test
  • \ifFPtest在输入流中释放。

然而,TeX 并不将其识别\FPifeq为条件,因此使用你的宏

\FPifeq#1{1}{}\else\FPifeq#1{-1}{-}\else#1\fi\fi

发生以下情况

  • #1是时1,然后\ifFPtest\iftrue,我们最终得到

    \iftrue{}\else\FPifeq#1{-1}{-}\else#1\fi\fi
    

    现在{}会留在输入流中,\else会删除匹配 之前的所有内容\fi。哦,不!还有\fi剩余!

  • #1不是时1,则\ifFPtest\iffalse,最后我们得到

    \iffalse{}\else\FPifeq#1{-1}{-}\else#1\fi\fi
    

    现在一切都\else被移除了,我们仍然

    \FPifeq#1{-1}{-}\else#1\fi\fi
    

    但 TeX 会记得它已经删除了\else。然后一切都会正常进行,因为在作业的末尾,或\FPifeq都会产生结果。尾随对应于预先删除的 ,因此不会造成损害。\iftrue\iffalse\fi\else

您的代码中存在一些小问题:它应该贯穿{#1}始终,否则诸如121作为第一个参数的值\FPifeq作为2第二个参数。

可以修复嵌套问题

\newcommand{\FPeq}{TT\fi\FPifeq}
\newcommand\Unit[1]{%
  \if\FPeq{#1}{1}%
    % do nothing
  \else
    \if\FPeq{#1}{-1}%
      -%
    \else
      #1%
    \fi
  \fi
}

这是一个老把戏,用来\if使上述问题消失;如果\if展开,它会看到TT\fi,这会导致真实测试并将\FPifeq被执行;如果它在跳过的文本中,它将正确匹配相应的\else\fi

但是,使用\FPifeq会对最终的输出产生不良影响。让我们看一个例子:

\documentclass{article}
\usepackage[nomessages]{fp}

\newcommand{\FPeq}{TT\fi\FPifeq}
\newcommand\Unit[1]{%
  \if\FPeq{#1}{1}%
    % do nothing
  \else
    \if\FPeq{#1}{-1}%
      -%
    \else
      #1%
    \fi
  \fi
}

\begin{document}

$\Unit{2}x$ $\Unit{1}x$ $\Unit{-1}x$

$2x$ $x$ $-x$

\end{document}

在此处输入图片描述

你能看出问题所在吗? 的工作\FPifeq会创建一个空的数学原子,因此如果多项式是前导数,则减号将被视为二元运算符,而不是一元运算符。

使用 Phelype Oleinik 的代码时,问题并未显现expl3

答案2

你不需要这样做fp。TeX 可以使用 进行整数比较\ifnum。这:

\documentclass{article}
\newcommand\Unit[1]{%
  \ifnum#1=1
    % nothing
  \else
    \ifnum#1=-1
      -%
    \else
      #1%
    \fi
  \fi}
\begin{document}
\Unit{2}x \Unit{1}x \Unit{-1}x
\end{document}

生产2x x -x


如果要使用fp,则需要在另一个宏中隐藏第二个测试。显然fp不喜欢嵌套条件:

\newcommand\Unit[1]{%
  \FPifeq{#1}{1}%
    % nothing
  \else
    \UnitInner{#1}%
  \fi}
\newcommand\UnitInner[1]{%
  \FPifeq{#1}{-1}%
    -%
  \else
    #1%
  \fi}

但是,我建议您使用expl3它自己的 FPU。它更加灵活,并允许您轻松编写嵌套条件:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand \Unit { m }
  {
    \fp_compare:nF { #1 == 1 }
      {
        \fp_compare:nTF { #1 == -1 }
          { - }
          { #1 }
      }
  }
\ExplSyntaxOff
\begin{document}
\Unit{2}x \Unit{1}x \Unit{-1}x
\end{document}

相关内容