How can I compare two (not necessarily integer) variables?
\ifnum
can be used to compare numbers, but only if the latter are integers. However, you can use \ifdim
to compare fixed-point number. Note that you need to specify some unit (such as pt
), though.
You probably want a more general command like the one I've defined below (\equalitytest
), which compares the values of two arbitrary fixed-point numbers. You can always define your \abc
command based on my \equalitytest
command.
\documentclass{article}
\setlength{\parindent}{0pt}
\newcommand\equalitytest[2]
{%
Is #1\ equal to #2?
\ifdim#1pt=#2pt
Equal.\\
\else%
Not equal.\\
\fi%
}
\begin{document}
\equalitytest{0.5}{0.5}
\equalitytest{0.7}{.8}
\def\test{0.5}
\newcommand\abc[1]
{%
\equalitytest{#1}{\test}
}
\abc{0.9}
\end{document}
Edit: Direct answer to Pygmalion's post:
\documentclass{article}
\begin{document}
\def\test{0.5}
\newcommand{\abc}[1]{
\ifdim#1 pt=\test pt
Something % do something
\fi}
\abc{0.5} % does something
\abc{0.7} % does nothing
\end{document}
Jubobs answer shows, how TeX dimensions can be used to compare fixed point numbers. There are two limitations:
- The largest TeX dimension is
\maxdimen
= 16383.99998pt = 16384pt - 1sp. TeX will complain with! Dimension too large
, if larger values are tried. - The smallest TeX dimension is 1sp = 2-16pt ≈ 0.00001525878906pt.
As jfbu pointed out in the comment, the largest unit in
does not give an higher precision for the fractional part than the standard unit pt
because of the rounding of the fractional part to multiples of 2-16 ≈ 0.000015258789 due to TeX's scanning of the number.
The other extreme is unit sp
that ignores the fractional part. But the number can go up to 230-1 = 1073741824.
Package fp
Package fp
implements macro based fixed point arithmetic. From its readme
:
Fixed point arithmetic for TeX with numbers ranging from -999999999999999999.999999999999999999 to +999999999999999999.999999999999999999
The following example implements the comparison of fixed point numbers using package fp
:
\documentclass{article}
\usepackage{fp-basic}
\makeatletter
% \equalnumsthenelse{<number A>}{<number B>}{<then: A=B>}{<else: A≠B>}
\newcommand*{\equalnumsthenelse}[2]{%
\FPifeq{#1}{#2}%
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\begin{document}
\def\test{0.5}
\newcommand*{\abc}[1]{
\equalnumsthenelse{#1}{\test}{%
\[#1=\test\]%
}{%
\[#1\ne\test\]%
}%
}
\abc{0.5}
\abc{0.7}
\abc{0.500000000001}
\abc{1234567890}
\end{document}
In opposite to a simple \ifdim
, this method is not expandable because of \FPifeq
.
An alternative to be considered is l3fp
, included in expl3
.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\fpcompare}{ m m m }
{
% #1 = test to perform
% #2 = text for the true case
% #3 = text for the false case
\fp_compare:nTF { #1 } { #2 } { #3 }
}
\ExplSyntaxOff
\newcommand\test{0.5}
\newcommand{\abc}[1]{%
\fpcompare{#1=\test}{Something}{}%
}
\begin{document}
\verb|\abc{0.5}|: X\abc{0.5}X
\verb|\abc{0.7}|: X\abc{0.7}X
\verb|\abc{0.500000000001}|: X\abc{0.500000000001}X
\verb|\abc{1234567890}|: X\abc{1234567890}X
\edef\TEST{\fpcompare{0.5 = 0.5}{Equal}{Different}}\texttt{\meaning\TEST}\\
\TEST
\edef\TEST{\fpcompare{0.7 = .8}{Equal}{Different}}\texttt{\meaning\TEST}\\
\TEST
\fpcompare{3.141529653 = 355/113}{Equal}{Different}
\fpcompare{3.141529653 != 355/113}{Different}{Equal}
\fpcompare{2.718281828459045 = 2718.281828459045/1000}{Equal}{Different}
\end{document}
One can test for equality with <fp1> = <fp2>
, strict inequality with <fp1> < <fp2>
or <fp1> > <fp2>
, non strict inequality with <fp1> <= <fp2>
or <fp1> >= <fp2>
, inequality with <fp1> != <fp2>
.
In the example code, I show that the test is fully expandable. Consult interface3.pdf
, part XXI for more information about the syntax of <fp>
and size limitations.