2

I want to use 2 seperate commands to first execute a calculation on a number and then displaying the number with plus or minus using following code.

When trying to run it I get various errors. I think that propably \FPeval is causing problems.

\documentclass{scrbook}
\usepackage{fp}
\usepackage{ifthen}

\newcommand\MyHalf[1]{\FPeval\result{trunc(#1 / 2, 0)}\result}

\newcommand\MyDisplaySign[1]{\ifthenelse{#1<0}{$#1$}{$+#1$}}

\begin{document}

\MyHalf{12}

\MyDisplaySign{\MyHalf{12}}

\end{document}
1
  • \FPeval is not expandable, it assigns the result to \result, so you need to do the evaluation first and then pass \result to the expansion context in the numeric test. Sep 8, 2018 at 18:38

2 Answers 2

4

The problem is that for the \ifthenelse test compare #1<0, #1 has to be a number. But if you pass a macro that contains a number (or, in some way, expands to a number), that macro has to be expandable, so that \ifthenelse can performing the test. The problem, as David said in the comment, is that \FPeval is not expandable because it assigns the result to \result.

But \fp_eval:n is expandable :)

\documentclass{scrbook}

\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand\MyHalf
  { m }
  {
    \fp_eval:n { trunc ( #1 / 2, 0 ) }
  }
\NewExpandableDocumentCommand\MyDisplaySign
  { m }
  {
    \int_compare:nTF
    { #1 <= \c_zero_int }
    { $   #1 $ }
    { $ + #1 $ }
  }
\ExplSyntaxOff

\begin{document}

\MyHalf{12} % Prints 6

\MyDisplaySign{\MyHalf{12}} % Prints +6

\MyDisplaySign{\MyHalf{-12}} % Prints -6

\MyDisplaySign{\MyHalf{0}} % Doesn't print "+0" because 0 isn't larger than \c_zero_int, so the conditional evaluates to true

\MyDisplaySign{\MyHalf{-0}} % Prints -0 because of the leading sign

\end{document}

The only issue is with 0. With the code above you don't get the leading + sign because 0=0 is true, so the first (for negative numbers) is taken. If you want the leading + sign then you have to print the sign if the value is equal to zero too, but then with negative zero you get +-0, because -0=+0 and the sign is added too:

\documentclass{scrbook}

\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand\MyHalf
  { m }
  {
    \fp_eval:n { trunc ( #1 / 2, 0 ) }
  }
\NewExpandableDocumentCommand\MyDisplaySign
  { m }
  {
    \int_compare:nTF
    { #1 >= \c_zero_int }
    { $ + #1 $ }
    { $   #1 $ }
  }
\ExplSyntaxOff

\begin{document}

\MyHalf{12} % Prints 6

\MyDisplaySign{\MyHalf{12}} % Prints +6

\MyDisplaySign{\MyHalf{-12}} % Prints -6

\MyDisplaySign{\MyHalf{0}} % Prints +0

\MyDisplaySign{\MyHalf{-0}} % Prints +-0

\end{document}

The isn't, as far as I know, a way to get -0 and +0 correct without doing extra tests for this specific scenario.

4
  • ifthenelse does expand the argument in the test, the problem is rather that \FPeval is not expandable. (but using fp_eval is better, I agree:-) Sep 8, 2018 at 18:40
  • 1
    This would print +0 With \int_compare:nTF { #1 <= 0 } you'd solve the issue. Or reverse the test: \int_compare:nNnTF { #1 } > { 0 } { $+#1$ } { $#1$ }
    – egreg
    Sep 8, 2018 at 21:25
  • The changed version still prints +0.
    – egreg
    Sep 9, 2018 at 16:34
  • @egreg The second one. The first one prints 6, +6, −6, 0, −0. Sep 9, 2018 at 16:43
1
\documentclass{scrbook}
\usepackage{fp}
\usepackage{ifthen}

\newcommand\MyHalf[1]{\FPeval\result{trunc(#1 / 2, 0)}}

\newcommand\MyDisplaySign[1]{\ifthenelse{#1<0}{$#1$}{$+#1$}}

\begin{document}

\MyHalf{12}%
% Now the result is stored in the macro \result.
% Let's see the result:
\result

% Now let's see the result with preceding algebraic sign:
\MyDisplaySign{\result}

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .