Как использовать выражение для float?

Я знаю, что это действительно глупый вопрос, но я не знаю, как это сделать в bash:

20 / 30 * 100

Должно быть 66.67, но expr говорит 0, потому что не поддерживает float. Какая команда в Linux может заменить expr и выполнить это уравнение?


person lauriys    schedule 10.08.2009    source источник
comment
Извини, моя вина, моя максима!   -  person smok1    schedule 10.08.2009
comment
для математических операций попробуйте использовать bc или awk , а не bash или expr   -  person ghostdog74    schedule 10.08.2009


Ответы (6)


Как сообщается на странице руководства bash:

The shell allows arithmetic expressions to be evaluated, under certain circumstances...Evaluation is done in fixed-width integers with no check for overflow, though division by 0 is trapped and flagged as an error.

Вы можете умножить на 100 раньше, чтобы получить лучший частичный результат:

let j=20*100/30
echo $j

66

Или на большее число, кратное 10, и представьте десятичный разряд, которому он принадлежит:

let j=20*10000/30
echo $j

66666

person Conspicuous Compiler    schedule 10.08.2009
comment
Это может помочь, если вы опубликуете фактическую командную строку, которую вы использовали. (Я предполагаю, что вы использовали больше нулей, чем я.) Я выполнил приведенные выше команды перед публикацией и получил данные результаты. Пожалуйста, попробуйте их в первую очередь. - person Conspicuous Compiler; 10.08.2009
comment
Да, странно, я не помню, чтобы изначально ставили пробелы. Во всяком случае, попробуйте удалить пробелы и повторить. Я отредактировал свой пост, чтобы удалить проблемные пробелы. - person Conspicuous Compiler; 10.08.2009
comment
Вопрос заключался в том, чтобы иметь дело с числом с плавающей запятой; bash пусть возвращает целое число - person HidekiAI; 25.07.2013
comment
Да, HidekiAI, вот почему я говорю, представьте себе десятичный разряд там, где он должен быть. Возвращенный результат 66666 представляет фактическое значение 66666 * 10^-3. - person Conspicuous Compiler; 25.07.2013

bc сделает это за вас, но важен порядок.

> echo "scale = 2; 20 * 100 / 30" | bc
66.66
> echo "scale = 2; 20 / 30 * 100" | bc
66.00

или, для вашего конкретного случая:

> export ach_gs=2
> export ach_gs_max=3
> x=$(echo "scale = 2; $ach_gs * 100 / $ach_gs_max" | bc)
> echo $x
66.66

Какой бы метод вы ни выбрали, его можно включить в качестве функции, облегчающей вашу жизнь:

#!/bin/bash
function pct () {
    echo "scale = $3; $1 * 100 / $2" | bc
}

x=$(pct 2 3 2) ; echo $x # gives 66.66
x=$(pct 1 6 0) ; echo $x # gives 16
person paxdiablo    schedule 10.08.2009
comment
но я хочу сделать это в скрипте, полная строка: $ach_gs / $ach_gs_max * 100 - person lauriys; 10.08.2009
comment
@maxorq: вы могли заметить, что во всех приведенных другими примерах сначала выполняется умножение. Это научная вычислительная вещь — поскольку мы знаем, что слева от десятичного знака доступно больше цифр, чем справа, умножение идет первым, чтобы минимизировать потерю точности из-за округления. - person Conspicuous Compiler; 10.08.2009

Обычно я использую perl:

perl -e 'print 10 / 3'
person pgl    schedule 12.08.2009
comment
это должно быть очень простая проблема Perl, но эта команда отображает только пустую строку в моей системе. perl -e 'print "hello world"' тоже не работает. Но perl -e 'print "hello world\n"' работает как положено. - person Sébastien; 31.05.2014
comment
Боюсь, я не могу помочь. Все, что я могу предложить, это добавить , "\n" в конец выражения: perl -e 'print 10 / 3, "\n"' - person pgl; 02.06.2014
comment
Спасибо, этот обходной путь работает. (и ваша команда работает «как есть» в другой среде Linux) - person Sébastien; 02.06.2014
comment
Для питонистов среди нас: python -c "print 10.0/3.0" - person emazzotta; 18.12.2015

просто сделай это в awk

# awk 'BEGIN{print 20 / 30 * 100}'
66.6667

сохранить в переменную

# result=$(awk 'BEGIN{print 20 / 30 * 100}')
# echo $result
66.6667
person ghostdog74    schedule 10.08.2009
comment
Этот ответ очень неловкий. - person xdhmoore; 17.04.2017

> echo "20 / 30 * 100" | bc -l
66.66666666666666666600

Это упрощение ответа paxdiablo. Параметр -l устанавливает масштаб (количество знаков после запятой) равным 20. Он также загружает математическую библиотеку с триггерными функциями и другими вещами.

person bjc    schedule 14.09.2016

Еще один очевидный вариант:

python -c "print(20 / 30 * 100)"

если вы используете Python 3. В противном случае используйте python3.

person Jules G.M.    schedule 31.01.2020