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}
  • \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. – David Carlisle Sep 8 '18 at 18:38
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.

  • 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:-) – David Carlisle Sep 8 '18 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 '18 at 21:25
  • The changed version still prints +0. – egreg Sep 9 '18 at 16:34
  • @egreg The second one. The first one prints 6, +6, −6, 0, −0. – Phelype Oleinik Sep 9 '18 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}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.