Verzweigen Sie zu etwas, wenn ein Ausdruck nicht von fpeval ausgewertet werden kann

Verzweigen Sie zu etwas, wenn ein Ausdruck nicht von fpeval ausgewertet werden kann

Ich möchte einen \comparatorerweiterbaren Befehl entwerfen, der auf fpeval3 Zweigen basiert:

  • echter Zweigwenn der Vergleich gleich 1 ist
  • falscher Zweigwenn der Vergleich Null ergibt
  • ungültiger Zweigwenn der Vergleich nicht durchgeführt werden kann (anstatt einen Kompilierungsfehler zurückzugeben)

Hier ist der aktuelle Code, den ich verwende:

\documentclass[preview = true, varwidth = true]{standalone}

\usepackage{xparse}
\usepackage{xfp}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\compare}{r[] m m m m m}{
    \compare_evaluation:eeennn{#1}{#2}{#3}{#4}{#5}{#6}
}
\cs_new:Nn \compare_evaluation:nnnnnn{
    \compare_result:ennn{\fpeval{#2 #1 #3}}{#4}{#5}{#6}
}
\cs_new:Nn \compare_result:nnnn{
    \str_case:nnTF{#1}{
        {0}{#3}
        {1}{#2}
    }{}{#4}
}
\cs_generate_variant:Nn \compare_evaluation:nnnnnn{eeennn}
\cs_generate_variant:Nn \compare_result:nnnn{ennn}
\ExplSyntaxOff

\begin{document}
\begin{tabular}{c}
\compare[<]{1.5}{2.5}{true}{false}{invalid} \\
\compare[<]{2.5}{1.5}{true}{false}{invalid} \\
\compare[<]{xx}{xx}{true}{false}{invalid} \\ % CRASHES
\end{tabular}
\end{document}

das natürlich bei der letzten Zeile des Tests abstürzt.

FRAGE:Wie macht man es kompilierbar und verzweigt es richtig (hier zum Drucken invalid)?

Antwort1

Wenn Erweiterbarkeit keine Voraussetzung ist, können Sie die Syntax mit einem regulären Ausdruck überprüfen

Bildbeschreibung hier eingeben

\documentclass[preview = true, varwidth = true]{standalone}

% These only needed in old latex releases
% \usepackage{xparse}
% \usepackage{xfp}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\compare}{r[] m m m m m}{
    \compare_evaluation:eeennn{#1}{#2}{#3}{#4}{#5}{#6}
}
\cs_new:Nn \compare_evaluation:nnnnnn{
  \regex_match:nnTF
  {^[0-9]*(\.[0-9]*)?([eE][0-9]+)?@@@[0-9]*(\.[0-9]*)?([eE][0-9]+)?$}
  {#2@@@#3}
  {
    \compare_result:ennn{\fpeval{#2 #1 #3}}{#4}{#5}{#6}
  }
  {#6}
  }
\cs_new:Nn \compare_result:nnnn{
    \str_case:nnTF{#1}{
        {0}{#3}
        {1}{#2}
    }{}{#4}
}
\cs_generate_variant:Nn \compare_evaluation:nnnnnn{eeennn}
\cs_generate_variant:Nn \compare_result:nnnn{ennn}
\ExplSyntaxOff

\begin{document}
\begin{tabular}{c}
\compare[<]{1.5}{2.5}{true}{false}{invalid} \\
\compare[<]{2.5}{1.5}{true}{false}{invalid} \\
\compare[<]{2.5e2}{15e3}{true}{false}{invalid} \\
\compare[<]{xx}{xx}{true}{false}{invalid} \\ % CRASHES
\end{tabular}
\end{document}

hier ging ich davon aus @@@, dass es sicher als Trennzeichen verwendet werden kann. Sie können Regex separat für die beiden Argumente verwenden oder ein benutzerdefiniertes Befehls-Tken verwenden, aber dies zeigt die Grundidee. Außerdem hat der Regex in Grenzfällen möglicherweise nicht genau die gleiche Syntax wie l3fp (und deckt keine fp-Ausdrücke ab), erfasst aber die wichtigsten Literalsyntaxen.

verwandte Informationen