如何在 Bash 中比较两个浮点数?
我正在努力比较 Bash 脚本中的两个浮点数。我有两个变量,例如
let num1=3.17648e-22
let num2=1.5
现在,我只想对这两个数字进行简单的比较:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
不幸的是,我在正确处理可以是“电子格式”的 num1 时遇到一些问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(22)
更方便
使用 Bash 的数字上下文可以更方便地完成此操作:
解释
通过基本计算器命令
bc
进行管道传输返回 1 或 0。选项
-l
相当于--mathlib
;它加载标准数学库。将整个表达式括在双括号
(( ))
之间会将这些值分别转换为 true 或 false。请确保安装了
bc
基本计算器软件包。警告:指数表示法应写为
*10^
;不是E
,也不是e
。例如:
此处
讨论了克服此
bc
限制的策略。More conveniently
This can be done more conveniently using Bash's numeric context:
Explanation
Piping through the basic calculator command
bc
returns either 1 or 0.The option
-l
is equivalent to--mathlib
; it loads the standard math library.Enclosing the whole expression between double parenthesis
(( ))
will translate these values to respectively true or false.Please, ensure that the
bc
basic calculator package is installed.Caveat: Exponential notation should be written as
*10^
; notE
, nore
.For example:
Whereas
Strategies to overcome this
bc
limitation are discussed here.Bash 仅处理整数数学,但您可以使用 bc 命令,如下所示:
请注意,指数符号必须大写。
Bash handles only integer maths, but you can use the
bc
command as follows:Note that the exponent sign must be uppercase.
您可以将 AWK 与 Bash if 条件结合使用:
You can use AWK combined with a Bash if condition:
一个纯 Bash 解决方案,用于比较没有指数表示法、前导零或尾随零的浮点数:
逻辑运算符的顺序 很重要。整数部分作为数字进行比较,小数部分作为字符串进行比较。使用 这个方法。
它不会将浮点数与整数(不带点)进行比较。
A pure Bash solution for comparing floats without exponential notation, leading or trailing zeros:
The order of logical operators matters. Integer parts are compared as numbers and fractional parts are intentionally compared as strings. Variables are split into integer and fractional parts using this method.
It won't compare floats with integers (without dot).
对于非整数数学,最好使用 AWK 。您可以使用这个 Bash 实用函数:
并将其调用为:
It's better to use AWK for noninteger mathematics. You can use this Bash utility function:
And call it as:
比较软件包版本的数字时要小心,例如检查 grep 2.20 是否大于版本 2.6:
我用这样的 shell/AWK 函数解决了这样的问题:
Beware when comparing numbers that are package versions, like checking if grep 2.20 is greater than version 2.6:
I solved such problems with such a shell/AWK function:
支持所有可能的符号的解决方案,包括具有大写和小写指数的科学记数法(例如,
12.00e4
):A solution that supports all possible notations, including the scientific notation with both uppercase and lowercase exponents (e.g.,
12.00e4
):当然,如果您不需要真正的浮点算术,只需对美元值进行算术,其中总是恰好有两位小数,您可以删除点(实际上乘以 100)并比较结果整数。
这显然要求您确保两个值具有相同的小数位数。
Of course, if you don't need really floating-point arithmetic, just arithmetic on e.g. dollar values where there are always exactly two decimal digits, you might just drop the dot (effectively multiplying by 100) and compare the resulting integers.
This obviously requires you to be sure that both values have the same number of decimal places.
请检查下面编辑的代码:
这效果很好。
Please check the below edited code:
This works well.
AWK 和类似的工具(我正盯着你
sed
...)应该被扔进旧项目的垃圾箱,其中的代码每个人都不敢碰,因为它是用一种从不读的语言编写的。或者您是一个相对罕见的项目,需要优先考虑 CPU 使用优化而不是代码维护优化……在这种情况下,请继续。
如果没有,那么,只需使用可读且明确的东西,例如 Python。你的同事和未来的自己都会感谢你。您可以像所有其他代码一样将 Python 代码与 Bash 内联使用。
AWK and tools like it (I'm staring at you
sed
...) should be relegated to the dustbin of old projects, with code that everyone is too afraid to touch since it was written in a read-never language.Or you're the relatively rare project that needs to prioritize CPU usage optimization over code maintenance optimization... in which case, carry on.
If not, though, instead just use something readable and explicit, such as Python. Your fellow coders and future self will thank you. You can use Python code inline with Bash just like all the others.
我使用了这里的答案并将它们放入一个函数中。您可以这样使用它:
在本例中,一旦调用,
echo $result
将为1
,否则为0
。函数:
或者带有调试输出的版本:
只需将函数保存在单独的
.sh
文件中,并像这样包含它:I used the answers from here and put them in a function. You can use it like this:
Once called,
echo $result
will be1
in this case, otherwise0
.The function:
Or a version with debug output:
Just save the function in a separated
.sh
file and include it like this:为了简单和清晰起见,只需使用 AWK 进行计算,因为它是标准 Unix 工具,因此可能以 bc 并且在语法上更容易使用。
对于这个问题:
对于作为该问题的重复项而关闭的另一个问题:
我将其发布为'4.5:语法错误:算术运算符无效(错误标记为“.5”)' - 但代码似乎仍然有效。为什么?当它作为这个问题的重复项被关闭时,所以这里也适用。
For simplicity and clarity, just use AWK for the calculations as it's a standard Unix tool and so just as likely to be present as bc and much easier to work with syntactically.
For this question:
And for that other question that was closed as a duplicate of this one:
I was posting this as an answer to '4.5: syntax error: invalid arithmetic operator (error token is ".5")' - but the code still seems to work. Why? when it got closed as a duplicate of this question, so here it is as it applies here too.
此脚本可能会帮助我检查已安装的 Grails 版本是否更高超过最低要求。
This script may help where I'm checking if the installed Grails version is greater than the minimum required.
使用 KornShell。在 Bash 中,您可能需要单独比较小数部分:
Use KornShell. In Bash you may have to compare the decimal part separately:
使用这个:
Use this:
使用 bashj(一个支持 Java 的 Bash 变体),您只需编写(并且它是< /em> 易于阅读):
当然,bashj Bash/Java 混合提供了更多...
Using bashj, a Bash mutant with Java support, you just write (and it is easy to read):
Of course, the bashj Bash/Java hybridation offers much more...
一个非常简单的 Perl 解决方案:
这证明 Perl 确实理解科学数字表示的“E”表示法:
如果您的 shell 脚本中需要“if”语句,请在 perl 中使用 exit 命令:
请注意,在 shell 脚本中,命令返回0 表示成功,并通过“if”条件(因此执行 if 子句)。任何其他非零返回值都意味着失败。
A very simple perl solution:
This proves that perl really understands the 'E' notation for scientific numerical representation:
If you need a 'if' statment in your shell script, use exit command in perl:
Note that in shell script, a command returning 0 is a success, and passes the 'if' condition (so the if-clause is executed). Any other non-zero return values means a failure.
有一种简单的方法,它比 AWK 快一点,并且不需要安装
bc
。它利用sort
对浮点数进行排序的能力:当然,它不适用于相等的数字。
There's one simple approach which is a bit faster than AWK and does not require
bc
to be installed. It leveragessort
's ability to sort float numbers:Of course, it does not work for numbers that are equal.
只需将
echo
替换为 printf (它理解浮点数):Just replace the
echo
with a printf (it understands floats):单行解决方案
假设您有两个变量
A
和B
,A one-liner solution
Suppose you have two variables
A
andB
,这是一种基于
gawk+GMP
的方法,可以考虑更广泛的潜在输入:对于更明确的情况,它会给您一个
<
< 的明确答案。 code>,>
,或=
(目前纯整数情况)当它相对不明确时,它输出
Unicode
人物U+2248 ≈ ALMOST EQUAL TO
而不是不惜一切代价尝试解决它。大多数时候您不需要 1000 万的
PREC
;像PREC = 32767
这样的东西对于人们通常遇到的大多数场景来说已经足够好了。Here's a
gawk+GMP
based approach to account for a broader range of potential input :For more clear-cut cases, it'll give you back a definitive answer of
<
,>
, or=
(purely integer cases, for now)When it's relatively ambiguous, it outputs the
Unicode
characterU+2248 ≈ ALMOST EQUAL TO
instead of attempting to resolve it at all cost.Most of the time you won't need
PREC
of 10-million; something likePREC = 32767
is good enough for most scenarios one encounters on a typical basis.