Как сравнить два числа с плавающей точкой в ​​Bash? - PullRequest
113 голосов
/ 28 декабря 2011

Я очень стараюсь сравнить два числа с плавающей точкой в ​​скрипте 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, которая может быть "электронного формата". (

Любая помощь, советы приветствуются!

Ответы [ 17 ]

1 голос
/ 14 сентября 2013

Используйте оболочку korn, в bash вам, возможно, придется сравнить десятичную часть отдельно

#!/bin/ksh
X=0.2
Y=0.2
echo $X
echo $Y

if [[ $X -lt $Y ]]
then
     echo "X is less than Y"
elif [[ $X -gt $Y ]]
then
     echo "X is greater than Y"
elif [[ $X -eq $Y ]]
then
     echo "X is equal to Y"
fi
1 голос
/ 16 апреля 2019

проверьте приведенный ниже отредактированный код: -

#!/bin/bash

export num1=(3.17648*e-22)
export num2=1.5

st=$((`echo "$num1 < $num2"| bc`))
if [ $st -eq 1 ]
  then
    echo -e "$num1 < $num2"
  else
    echo -e "$num1 >= $num2"
fi

это хорошо работает.

0 голосов
/ 17 октября 2018

Решение, поддерживающее научную нотацию с показателем в верхнем и нижнем регистре (например, 12.00e4):

if (( $(bc -l <<< "${value1/e/E} < ${value2/e/E}") ))
then
    echo "$value1 is less than $value2"
fi 
0 голосов
/ 24 сентября 2018
num1=0.555
num2=2.555


if [ `echo "$num1>$num2"|bc` -eq 1 ]; then
       echo "$num1 is greater then $num2"
else
       echo "$num2 is greater then $num1"
fi
0 голосов
/ 19 июля 2017

awk и подобные ему инструменты (я смотрю на вас sed ...) должны быть отправлены на свалку старых проектов с кодом, который все слишком боятся трогать, поскольку он был написан в чтении-не языком.

Или вы относительно редкий проект, которому нужно расставить приоритеты оптимизации использования ЦП над оптимизацией обслуживания кода ... в таком случае продолжайте.почему бы вместо этого просто использовать что-то читаемое и явное, такое как python?Ваши коллеги по программированию и будущие я будут вам благодарны.Вы можете использовать python inline с bash, как и все остальные.

num1=3.17648E-22
num2=1.5
if python -c "exit(0 if $num1 < $num2 else 1)"; then
    echo "yes, $num1 < $num2"
else
    echo "no, $num1 >= $num2"
fi
0 голосов
/ 02 июня 2019

Я публиковал это как ответ на https://stackoverflow.com/a/56415379/1745001, когда он был закрыт как дубликат этого вопроса, так что здесь, как и здесь:

Для простоты и ясности просто используйте awkдля вычислений, так как это стандартный инструмент UNIX и поэтому с такой же вероятностью будет присутствовать как bc, и с ним намного проще работать синтаксически.

Для этого вопроса:

$ cat tst.sh
#!/bin/bash

num1=3.17648e-22
num2=1.5

awk -v num1="$num1" -v num2="$num2" '
BEGIN {
    print "num1", (num1 < num2 ? "<" : ">="), "num2"
}
'

$ ./tst.sh
num1 < num2

и для другихвопрос, который был закрыт как дубликат этого:

$ cat tst.sh
#!/bin/bash

read -p "Operator: " operator
read -p "First number: " ch1
read -p "Second number: " ch2

awk -v ch1="$ch1" -v ch2="$ch2" -v op="$operator" '
BEGIN {
    if ( ( op == "/" ) && ( ch2 == 0 ) ) {
        print "Nope..."
    }
    else {
        print ch1 '"$operator"' ch2
    }
}
'

$ ./tst.sh
Operator: /
First number: 4.5
Second number: 2
2.25

$ ./tst.sh
Operator: /
First number: 4.5
Second number: 0
Nope...
0 голосов
/ 30 мая 2017

Как насчет этого? = D * * тысяча одна

VAL_TO_CHECK="1.00001"
if [ $(awk '{printf($1 >= $2) ? 1 : 0}' <<<" $VAL_TO_CHECK 1 ") -eq 1 ] ; then
    echo "$VAL_TO_CHECK >= 1"
else
    echo "$VAL_TO_CHECK < 1"
fi
...