我从外部 CSV 文件中读取五个值,作为 [ \sone
,\stwo
,\sthree
,\sfour
,\sfive
]。样本值可以是 [55.3, 89.0, 33.5, 40, 0.10]。
问题 :
如何比较带小数点的数字。例如,我可以使用 比较数字
\ifnum\sone=1
,但它不接受小数点。如何应用逻辑或者打印相应语句的条件?例如,
中频
\sone
> 70.4或者\stwo
> 80.33或者\sthree
<= 33.0或者\sfour
= 80或者\sfive
>= 0.11 THEN
打印此行
ELSE 打印其他行
END IF
答案1
“传统”方法是老式方法。也就是说,将数字转换为长度/尺寸(可以包含小数值,如),然后使用而不是2.5pt
进行比较。\ifdim
\ifnum
逻辑运算如或者和和使用基本\if...<true>\else<false>\fi
结构,根据需要混合和匹配以获得所需的输出。例如,逻辑或者可能
\if...<true>\else\if...<true>\fi\fi
虽然合乎逻辑和可能
\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}
为了避免在最后一条语句中出现大量重复,我创建了一个布尔值\ifcondition
,并将其设置为 true -\conditiontrue
如果满足任何一种情况。否则它仍为 false - \conditionfalse
。我还在嵌套的条件字符串中加入了条件满足的位置。
etoolbox
通过使用 ,可以根据需要混合逻辑运算符,大大“简化”了此输入\ifboolexpr{<expression>}{<true>}{<false>}
。上面的 MWE 使用以下布尔表达式语法复制etoolbox
:
\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>}
用于评估除基本 TeX\if
条件之外的任何布尔表达式,并且允许分组/嵌套。阅读有关这些测试的更多信息,请参阅以下章节3.6.4 算术测试和3.6.5 布尔表达式(第 18-23 页)etoolbox
文档。
etoolbox
顺便说一句,应该在每个 LaTeX 用户的工具箱中。
如果您的数字都具有相同的结构,例如XXX.XX
,那么您也可以使用 pdfTeX 的\pdfstrcmp{<string1>}{<string2>}
。此命令比较两个字符串,如果字符串相等,则扩展为 0 ( <string1> = <string2>
),如果第一个字符串排在第二个字符串之前,则扩展为 -1 ( <string1> < <string2>
),否则扩展为 1 ( <string1> > <string2>
)。此原语是在 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}
答案2
可以使用l3fp
以下设施:
\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}
这输出
打印此行
打印此另一行
还可以在子表达式、否定运算符!
和与运算符周围使用括号&&
。
答案3
您可以比较数值数量(带小数点、科学计数法或分数),并使用以下方法组合数值条件信特压裂,以及,为了更容易输入语法xintexpr。
更新为xintexpr自原始答案以来已经得到扩展。
\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}
答案4
如果您已经使用TikZ
(3.0.0+),则可以使用math
库。但不要TikZ
只为此加载,其他答案(可能)比这个更轻量且更快。
\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{
int \answer;
if ( \sone > 70.4 || \stwo < 80.33 || \sthree*\sfive <= \sfour-35 ) then {
\answer = 43*sin(\stwo);
{The third inequality is true, so ...\newline};
} else {
\answer = 0;
{This will not be printed.};
};
}
% Output the result
the Answer to the Ultimate Question of Life, the Universe, and Everything is: \answer
\end{document}