如何在shell脚本中比较两个浮点数

如何在shell脚本中比较两个浮点数

我想在 shell 脚本中比较两个浮点数。以下代码不起作用:

#!/bin/bash   
min=12.45
val=10.35    
if (( $val < $min )) ; then    
  min=$val
fi
echo $min 

答案1

Bash 不理解浮点运算。它将包含小数点的数字视为字符串。

请改用 awk 或 bc。

#!/bin/bash

min=12.45
val=10.35

if [ 1 -eq "$(echo "${val} < ${min}" | bc)" ]
then  
    min=${val}
fi

echo "$min"

如果您打算进行大量数学运算,最好依靠 python 或 perl。

答案2

您可以使用包数字实用程序 用于简单的操作...

对于更严肃的数学,请参阅这个链接...它描述了几个选项,例如。

  • R / R脚本(GNU R统计计算和图形系统)
  • 八度(主要与 Matlab 兼容)
  • bc(GNU bc 任意精度计算器语言)

一个例子numprocess

echo "123.456" | numprocess /+33.267,%2.33777/
# 67.0395291239087  

A programs for dealing with numbers from the command line

The 'num-utils' are a set of programs for dealing with numbers from the
Unix command line. Much like the other Unix command line utilities like
grep, awk, sort, cut, etc. these utilities work on data from both
standard in and data from files.

Includes these programs:
 * numaverage: A program for calculating the average of numbers.
 * numbound: Finds the boundary numbers (min and max) of input.
 * numinterval: Shows the numeric intervals between each number in a sequence.
 * numnormalize: Normalizes a set of numbers between 0 and 1 by default.
 * numgrep: Like normal grep, but for sets of numbers.
 * numprocess: Do mathematical operations on numbers.
 * numsum: Add up all the numbers.
 * numrandom: Generate a random number from a given expression.
 * numrange: Generate a set of numbers in a range expression.
 * numround: Round each number according to its value.

这是一个bashhack...它将前导 0 添加到整数以使字符串从左到右的比较有意义。这段特定的代码要求两者 分钟瓦尔实际上有一个小数点和至少一位小数。

min=12.45
val=10.35

MIN=0; VAL=1 # named array indexes, for clarity
IFS=.; tmp=($min $val); unset IFS 
tmp=($(printf -- "%09d.%s\n" ${tmp[@]}))
[[ ${tmp[VAL]} < ${tmp[MIN]} ]] && min=$val
echo min=$min

输出:

min=10.35

答案3

对于浮点数的简单计算(+-*/ 和比较),可以使用 awk。

min=$(echo 12.45 10.35 | awk '{if ($1 < $2) print $1; else print $2}')

或者,如果您有 ksh93 或 zsh(不是 bash),则可以使用 shell 的内置算术,它支持浮点数。

if ((min>val)); then ((val=min)); fi

对于更高级的浮点计算,请查找公元前。它实际上适用于任意精度的定点数字。

要处理数字表,请查找例子)。

答案4

使用数字排序

该命令sort有一个选项-g( --general-numeric-sort),可用于通过查找最小值或最大值来比较<“小于”或>“大于”。

这些示例正在寻找最小值:

$ printf '12.45\n10.35\n' | sort -g | head -1
10.35

支持电子记数法

它适用于非常通用的浮点数表示法,例如电子表示法

$ printf '12.45E-10\n10.35\n' | sort -g | head -1
12.45E-10

注意E-10,第一个数字0.000000001245,确实小于10.35

可以与无穷大相比较

浮点标准,IEEE754,定义一些特殊值。对于这些比较,有趣的是INF无穷大。还有负无穷;两者都是标准中明确定义的值。

$ printf 'INF\n10.35\n' | sort -g | head -1
10.35
$ printf '-INF\n10.35\n' | sort -g | head -1
-INF

要找到最大用途sort -gr而不是sort -g,请颠倒排序顺序:

$ printf '12.45\n10.35\n' | sort -gr | head -1
12.45

比较运算

要实现<(“小于”)比较,以便可以在if等中使用,请将最小值与其中一个值进行比较。如果最小值等于该值,作为文本进行比较,它小于另一个值:

$ a=12.45; b=10.35                                    
$ [ "$a" = "$(printf "$a\n$b\n" | sort -g | head -1)" ]
$ echo $?
1
$ a=12.45; b=100.35                                    
$ [ "$a" = "$(printf "$a\n$b\n" | sort -g | head -1)" ]
$ echo $?                                              
0

相关内容