# How to test if a number is negative

Is there an easy way to test if a number is negative?

I don't need a general solution, but it does need to be able to handle a floating point value. I was using this solution from tex.ac.uk until I realized that it has problems with positive floating point numbers. Here is a test file

\documentclass{article}

\def\IsPositive#1{%
TT\fi%
\ifcat_\ifnum0<0#1 _\else A\fi%
}

\newcommand{\PrintSignOfNumber}[1]{%
\if\IsPositive{#1}%
$#1 \ge 0$%
\else%
$#1 < 0$%
\fi%
}

\begin{document}

\PrintSignOfNumber{2}\par
\PrintSignOfNumber{-2}

\PrintSignOfNumber{2.0}\par  % reported as negative
\PrintSignOfNumber{-2.0}

\end{document}


I don't need a very general solution. Even if it just tested the first character as being a negative sign would suffice for my application. I would think that the etoolbox could do this easily, but I can't quite figure out how. If anyone knows of a good document that contains examples of using etoolbox that would be great.

If you are an adept of TikZ, the next solution is for you (with pgf 2.1)

\documentclass[]{scrartcl}
\usepackage{tikz}
\newcommand\test[1]{
\pgfmathsetmacro{\var}{#1}
\pgfmathparse{ifthenelse(\var>=0,"positif","négatif")} \pgfmathresult}%

\begin{document}

\test{1}   \test{-2} \test{cos(95)}

\end{document}


Modified version :

\documentclass[]{scrartcl}
\usepackage{tikz}

\newcommand\ifPositif[3]{
\begingroup
\pgfmathsetmacro{\var}{#1}
\pgfmathparse{ifthenelse(\var>=0,1,0)}
\ifdim\pgfmathresult pt= 1 pt
#2
\else
#3
\fi
\endgroup
}

\begin{document}

\ifPositif{1}{pos}{neg}

\ifPositif{2-2}{\pgfmathparse{sqrt(3)} \pgfmathresult}
{\pgfmathparse{sqrt(2)} \pgfmathresult}

\ifPositif{cos(95)+sqrt(2)}{\pgfmathparse{sqrt(5)} \pgfmathresult}
{\pgfmathparse{sqrt(6)} \pgfmathresult}

\ifPositif{-1e-2}{pos}{neg}

\ifPositif{1-5e2}{\var}{\foreach \x in {1,2}{\x}}

\ifPositif{1-5e2}{\var}{\var}
\end{document}

• All the solutions here work great. I like this the best as it is a lot more flexible, but I would prefer to have a wrapper macro so when I need to use this I can just say something like \ifPositive{}{do this}{else do this}. I'm going to try to attempt to do this, but I am still only at the hacker stage when it comes to TeX – Peter Grill Apr 8 '11 at 17:53
• @Peter I add the wrapper macro. – Alain Matthes Apr 8 '11 at 19:08
• Works great. Not sure I fully understand the comparison to "1 pt". – Peter Grill Apr 8 '11 at 19:27
• @Peter you can use \if\pgfmathresult 1 \relax instead of \ifdim – Alain Matthes Apr 8 '11 at 19:42
• Just a minor remark: zero is neither positive nor negative; you could modify your example codes so that 0 is not reported as positive. – Gonzalo Medina Apr 8 '11 at 23:11

An easy way is to use a simple macro and test if the number is less than zero.

\documentclass{article}
\begin{document}

\def\test#1{%
\expandafter\ifnum#1<0 isNegative \else isPositive\fi
}
\test{-23}

\test{23}
\end{document}


For decimal numbers, modify as:

\documentclass{article}
\usepackage{fp}
\begin{document}

\def\test#1{%
\expandafter\ifnum#1<0 isNegative \else isPositive\fi
}
\test{-23}

\test{23}

\def\testReal#1{%
\FPiflt{#1}{0} isNegative\else isPositive\fi
}

\testReal{-23.789}
\end{document}

• For your second solution (the one using fp) you could also use fp-basic's macros \FPifneg#1 ...\else...\fi, \FPifpos#1 ...\else...\fi, and \FPifzero#1...\else...\fi. Also, just a minor remark: zero is neither positive nor negative. – Gonzalo Medina Apr 8 '11 at 23:17
• @Gonzalo thanks for the comments and yes the code should have a test for zero as well. – Yiannis Lazarides Apr 10 '11 at 21:33

You can use \@ifnextchar{<char>}{<true>}{<false>} to check if the next character (actually next token) is -. I would also recommend to not use some \if TT\fi trickery but use a if-macro which accepts the true and false branches as arguments.

Here the argument is unbraced by the first macro and placed behind \@ifnextchar which is normally the last element in a macro to read the next character after it. The rest of the argument is then removed by \remove@to@nnil which removes everything to \@nnil. All of these macros are from the LaTeX kernel.

\documentclass{article}

\makeatletter
\def\ifPositive#1{%
\@ifnextchar{-}%
{\expandafter\@secondoftwo\remove@to@nnil}%
{\expandafter\@firstoftwo\remove@to@nnil}%
#1\@nnil
}
\makeatother

\newcommand{\PrintSignOfNumber}[1]{%
\ifPositive{#1}%
{$#1 \ge 0$}%
{$#1 < 0$}
}

\begin{document}

\PrintSignOfNumber{2}\par
\PrintSignOfNumber{-2}

\PrintSignOfNumber{2.0}\par
\PrintSignOfNumber{-2.0}

\end{document}


Prints:

 2 >= 0
-2 < 0
2:0 >= 0
-2:0 < 0


If your really want if-switches then you can do it like follows. Just make sure that the macro definition isn't inside a conditionals, otherwise the \fi, \iftrue and \iffalse will confuse TeX.

\documentclass{article}

\makeatletter
\def\isPositive#1{%
TT\fi
\@ifnextchar{-}%
{\expandafter\iffalse\remove@to@nnil}%
{\expandafter\iftrue\remove@to@nnil}%
#1\@nnil
}
\makeatother

\newcommand{\PrintSignOfNumber}[1]{%
\if\isPositive{#1}%
$#1 \ge 0$%
\else
$#1 < 0$
\fi
}

\begin{document}

\PrintSignOfNumber{2}\par
\PrintSignOfNumber{-2}

\PrintSignOfNumber{2.0}\par
\PrintSignOfNumber{-2.0}

\end{document}

\documentclass{article}

\makeatletter
\newcommand\PrintSignOfNumber[1]{%
\ifdim#1pt<\z@ $#1<0$\else$#1\ge0$\fi}
\makeatother

\begin{document}

\PrintSignOfNumber{2}\par
\PrintSignOfNumber{-2}

\PrintSignOfNumber{2.0}\par
\PrintSignOfNumber{-2.0}

\end{document}

• +1 This would be the simplest way to go. However one drawback is that it will cause a TeX compile error if the argument is not a number (anything else than +/-, digits, .). This is of course a general problem, but other solutions would be simple wrong, not causing an error. Ok, sometimes an error is what you want. This points you directly to the wrong input. – Martin Scharrer Apr 8 '11 at 13:12
• it is also simple to check whether I have a valid dimension or not ... And, by the way: my solution also works for 2,1 which will be friendly to us germans :-) – user2478 Apr 8 '11 at 13:34
• Nice. I didn't know that TeX accepts a , as well. – Martin Scharrer Apr 8 '11 at 13:37
• Actually, I don't consider that a drawback. Its much more preferable to get a compile error rather than silently do the wrong thing. – Peter Grill Apr 8 '11 at 17:50
• Nice solution.. – Gonzalo Medina Apr 8 '11 at 21:02

This method works regardless of integer or real type argument

\documentclass{article}
\usepackage{stringstrings}
\newcommand\PrintSignOfNumber[1]{%
\isnextbyte[q]{-}{#1}%
\if T\theresult$#1 < 0$\else$#1 \ge 0$\fi%
}
\begin{document}
\PrintSignOfNumber{2}\par
\PrintSignOfNumber{-2}\par
\PrintSignOfNumber{2.0}\par
\PrintSignOfNumber{-2.0}
\end{document}