# How to compare numbers with decimal point and logical OR operation?

I'm reading five values from external CSV file as [\sone, \stwo, \sthree, \sfour, \sfive]. Sample values could be [55.3, 89.0, 33.5, 40, 0.10].

Question :

1. How to compare number with decimal points. For example, I can compare numbers using \ifnum\sone=1, but it does not accept decimal point.

2. How to apply logical OR condition for printing respective statements? For example,

IF \sone > 70.4 OR \stwo > 80.33 OR \sthree <= 33.0 OR \sfour = 80 OR \sfive >= 0.11 THEN
Print this line
ELSE Print other line
END IF

The "traditional" way is the old-school way. That is, you convert the numbers into lengths/dimensions (that can contain decimal values, like 2.5pt) and perform the comparison using \ifdim rather than \ifnum.

Logical operations like OR and AND are performed using the basic \if...<true>\else<false>\fi structure, mixing and match as required to obtain the required output. For example, logical OR could be

\if...<true>\else\if...<true>\fi\fi


while logical AND could be

\if...\if...<true>\fi\fi


\documentclass{article}
\def\sone{55.3}
\def\stwo{89.0}
\def\sthree{33.5}
\def\sfour{40}
\def\sfive{0.10}
\begin{document}

two \ifdim\stwo pt<\sthree pt $<$\else $\geq$\fi{} three \par
five \ifdim\sfive pt<\sfour pt $<$\else $\geq$\fi{} four \par

\newif\ifcondition\conditionfalse

\ifdim\sone pt>70.4pt A\conditiontrue\else
\ifdim\stwo pt>80.33pt B\conditiontrue\else
\ifdim\sthree pt<33.0pt C\conditiontrue\else
\ifdim\sthree pt=33.0pt D\conditiontrue\else
\ifdim\sfour pt=80pt E\conditiontrue\else
\ifdim\sfive pt>0.11pt F\conditiontrue\else
\ifdim\sfive pt=0.11pt G\conditiontrue%\else
\fi\fi\fi\fi\fi\fi\fi

\ifcondition thisline\else otherline\fi

\end{document}


To avoid great duplication in the last clause, I've created a boolean \ifcondition and set it to true - \conditiontrue - if any one of the cases are met. Otherwise it remains false - \conditionfalse. I've additionally included where the condition is met with the nested string of conditionals.

etoolbox "simplifies" this input greatly with the ability to mix logical operators as needed using \ifboolexpr{<expression>}{<true>}{<false>}. The above MWE is replicated using the etoolbox boolean expression syntax below:

\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\def\sone{55.3}
\def\stwo{89.0}
\def\sthree{33.5}
\def\sfour{40.0}
\def\sfive{0.1}
\begin{document}

two
\ifboolexpr{
test {\ifdimless{\stwo pt}{\sthree pt}}
}
{$<$} % true
{$\geq$} % false
three

five
\ifboolexpr{
test {\ifdimless{\sfive pt}{\sfour pt}}
}
{$<$} % true
{$\geq$} % false
four

\ifboolexpr{
test {\ifdimgreater{\sone pt}{70.4pt}} or
test {\ifdimgreater{\stwo pt}{80.33pt}} or
(test {\ifdimless{\sthree pt}{33.0pt}} or test {\ifdimequal{\sthree pt}{33.0pt}}) or
test {\ifdimequal{\sfour pt}{80pt}} or
(test {\ifdimgreater{\sfive pt}{0.11pt}} or test {\ifdimequal{\sfive pt}{0.11pt}})
}
{thisline} % true
{otherline} % false

\end{document}


test {<bool expression>} is used to evaluate any boolean expression other than the basic TeX \if-conditionals, and grouping/nesting is allowed. Read more about these tests in sections 3.6.4 Arithmetic Tests and 3.6.5 Boolean Expressions (p 18-23) of the etoolbox documentation.

etoolbox, by the way, should be in every LaTeX-user's toolkit.

If your numbers all have the same structure, say XXX.XX, then you can also use pdfTeX's \pdfstrcmp{<string1>}{<string2>}. This command compares two strings and expands to 0 if the strings are equal (<string1> = <string2>), to -1 if the first string ranks before the second (<string1> < <string2>), and to 1 otherwise (<string1> > <string2>). The primitive was introduced in pdfTEX 1.30.0.

\documentclass{article}
\def\sone{55.3}
\def\stwo{89.0}
\def\sthree{33.5}
\def\sfour{40.0}
\def\sfive{00.1}
\begin{document}

\ifnum\pdfstrcmp{\stwo}{\sthree}=-1 two $<$ three \else two $\geq$ three\fi \par
\ifnum\pdfstrcmp{\sfive}{\sfour}=-1 five $<$ four \else five $\geq$ four\fi \par

\end{document}

• Thanks a lot Sir. I've learnt a lot from your post. Now, I'm able to compare required numbers. – Pawan Mude Oct 5 '13 at 4:19
• Quote: logical OR could be \if...<true>\else\if...<true>\fi\fi end quote. You see, the <true> part has to be written twice. Is it possilbe to write <true> part only once in logical OR with Tex primitives like it does in logical AND you give? – lyl Feb 27 at 10:34

One can use l3fp facilities:

\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\booltest}{mmm}
{
\bool_if:nTF { #1 } { #2 } { #3 }
}
\DeclareExpandableDocumentCommand{\fpcompare}{m}
{
\fp_compare_p:n { #1 }
}
\ExplSyntaxOff

\begin{document}

\def\sone{55.3}
\def\stwo{89.0}
\def\sthree{33.5}
\def\sfour{40}
\def\sfive{0.10}

\booltest{
\fpcompare{\sone > 0.74} ||
\fpcompare{\stwo > 80.33} ||
\fpcompare{\sthree <= 33.0} ||
\fpcompare{\sfour = 80} ||
\fpcompare{\sfive >= 0.11}
}
{Print this line}
{Print this other line}

\def\sone{0.73}
\def\stwo{80}
\booltest{
\fpcompare{\sone > 0.74} ||
\fpcompare{\stwo > 80.33} ||
\fpcompare{\sthree <= 33.0} ||
\fpcompare{\sfour = 80} ||
\fpcompare{\sfive >= 0.11}
}
{Print this line}
{Print this other line}

\end{document}


This outputs

Print this line
Print this other line

One can also use parentheses around subexpressions, the negation operator ! and the and operator &&.

• I would gladly upvote, but that would break the current draw in upvotes to your advantage ... ;-) – user4686 Oct 5 '13 at 13:55
• my count moved up, so I did upvote l3fp... can't do anything more now ;-) – user4686 Oct 5 '13 at 13:59
• @jfbu Now it's not a draw, as I upvoted yours. – egreg Oct 5 '13 at 13:59
• molto bravo! grazie. – user4686 Oct 5 '13 at 14:00

You can compare numerical quantities (with decimal points, scientific notation or fractions) and combine numerical conditions using xintfrac, and, for easier input syntax xintexpr.

Updated as xintexpr has been expanded since original answer.

\documentclass{article}
\usepackage{xintexpr}% version 1.1 or later.

\begin{document}
\def\sone{55.3}
\def\stwo{89.0}
\def\sthree{33.5}
\def\sfour{40}
\def\sfive{0.10}

\xintifboolexpr {  \sone > 70.4  ||  \stwo > 80.33 || \sthree <= 33.0 ||
\sfour = 80 || \sfive >= 0.11 }
{At least one of the inequalities is true}
{None of the tested inequalities is true}

% Alternative syntax:

\xintifboolexpr {  \sone > 70.4  'or'  \stwo > 80.33 'or' \sthree <= 33.0 'or'
\sfour = 80 'or' \sfive >= 0.11 }
{At least one of the inequalities is true}
{None of the tested inequalities is true}

\xintifboolexpr {any(\sone > 70.4, \stwo > 80.33 , \sthree <= 33.0,
\sfour = 80, \sfive >= 0.11)}
{At least one of the inequalities is true}
{None of the tested inequalities is true}

\xintifboolexpr { 3.5 > 3.4 'and' (-123 > -123.1 'or' -123 > -122.9) }
{YES}
{NO}

% equivalently

\xintifboolexpr { 3.5 > 3.4 && (-123 > -123.1 || -123 > -122.9)}
{YES}
{NO}

\end{document}


If you already use TikZ (3.0.0+) you can use math library. But do not load TikZ just for this, the other answers are (probably) lighter and faster than this one.

\documentclass[varwidth,border=50]{standalone}
\usepackage{tikz}
\usetikzlibrary{math}

\begin{document}
% define all constants
\def\sone{55.3}
\def\stwo{89.0}
\def\sthree{33.5}
\def\sfour{40}
\def\sfive{0.10}
% make a decision
\tikzmath{