Я хочу сравнить два числа с плавающей точкой в сценарии оболочки. Следующий код не работает:
#!/bin/bash
min=12.45
val=10.35
if (( $val < $min )) ; then
min=$val
fi
echo $min
shell
shell-script
arithmetic
Ричард Уильямс
источник
источник
0.5
и0.06
). Вам лучше использовать инструмент, который уже понимает десятичную запись.1.00000000000000000000000001
больше, чем2
.Bash не понимает арифметику с плавающей точкой. Числа, содержащие десятичную точку, обрабатываются как строки.
Используйте вместо этого awk или bc.
Если вы собираетесь выполнять много математических операций, возможно, лучше использовать Python или Perl.
источник
Вы можете использовать пакет num-utils для простых манипуляций ...
Для более серьезной математики, смотрите эту ссылку ... Он описывает несколько вариантов, например.
Пример
numprocess
Вот
bash
хак ... Он добавляет начальные 0 к целому числу, чтобы сделать сравнение строк слева направо значимым. Этот конкретный фрагмент кода требует, чтобы и min, и val фактически имели десятичную точку и хотя бы одну десятичную цифру.выход:
источник
Для простых вычислений с числами с плавающей запятой (+ - * / и сравнения) вы можете использовать awk.
Или, если у вас ksh93 или zsh (не bash), вы можете использовать встроенную арифметику вашей оболочки, которая поддерживает числа с плавающей запятой.
Для более сложных вычислений с плавающей запятой посмотрите bc . На самом деле он работает с числами с произвольной точностью.
Для работы с таблицами чисел найдите R ( пример ).
источник
Использовать числовую сортировку
У команды
sort
есть опция-g
(--general-numeric-sort
), которую можно использовать для сравнения значений<
«меньше чем» или>
«больше чем» путем нахождения минимума или максимума.Эти примеры находят минимум:
Поддерживает электронную нотацию
Он работает с довольно общими обозначениями чисел с плавающей запятой, как с E-Notation
Обратите внимание на то
E-10
, что первое число0.000000001245
действительно меньше10.35
.Можно сравнить с бесконечностью
Стандарт с плавающей запятой, IEEE754 , определяет некоторые специальные значения. Для этих сравнений самые интересные
INF
для бесконечности. Существует также отрицательная бесконечность; Оба хорошо определены значения в стандарте.Чтобы найти максимальное использование
sort -gr
вместо тогоsort -g
, чтобы изменить порядок сортировки:Операция сравнения
Чтобы реализовать
<
сравнение («меньше чем»), чтобы его можно было использовать вif
etc, сравните минимум с одним из значений. Если минимум равен значению, сравнивается как текст , он меньше другого значения:источник
a == min(a, b)
такая же какa <= b
. Стоит отметить, что это не проверяет строго меньше, чем, хотя. Если вы хотите сделать это, вы должны проверитьa == min(a, b) && a != max(a, b)
, другими словамиa <= b and not a >= b
Просто используйте
ksh
(ksh93
точно) илиzsh
, которые изначально поддерживают арифметику с плавающей запятой:Изменить: Извините, я пропустил
ksh93
уже было предложено. Сохраняя мой ответ, просто чтобы прояснить, сценарий, опубликованный во вступительном вопросе, может использоваться без изменений вне переключателя оболочки.Edit2: обратите внимание, что
ksh93
требуется, чтобы содержимое переменной было согласовано с вашей локалью, то есть с французской локалью, вместо точки должна использоваться запятая:Более надежное решение - установить языковой стандарт в начале скрипта, чтобы он работал независимо от языкового стандарта пользователя:
источник
.
(поэтому не в половине мира, где есть десятичный разделитель,
).zsh
не имеет этой проблемы.LC_ALL
, это также означает, что числа не будут отображаться (или вводиться) в предпочтительном формате пользователя. См. Unix.stackexchange.com/questions/87745/what-does-lc-all-c-do/… для потенциально лучшего подхода..
любом случае.Это использует
dc
калькулятор, чтобы порватьs
значение для$min
в регистреa
иd
помещает значение$val
на вершину его основного стека выполнения. Затем онl
помещает содержимоеa
на вершину стека, и в этот момент он выглядит следующим образом:<
Выскакивает две верхние записи из стека и сравнивает их. Таким образом, стек выглядит так:Если верхняя запись была меньше, чем вторая, она помещает содержимое
a
в верхнюю часть, поэтому стек выглядит так:Иначе это ничего не делает, и стек все еще выглядит так:
Тогда это просто
p
набирает запись верхнего стека.Итак, для вашей проблемы:
Но:
источник
Почему бы не использовать старое, хорошее
expr
?Пример синтаксиса:
Для истинных выражений код выхода expr равен 0, а строка '1' отправляется на стандартный вывод. Обратное для ложного выражений.
Я проверил это с GNU и FreeBSD 8 expr.
источник
expr 1.09 '<' -1.1
напечатает1
и выйдет с0
(успехом).Чтобы проверить, в порядке ли два (возможно, дробных) числа,
sort
(разумно) переносимо:Однако, если вы действительно хотите сохранить минимальное значение обновленным, тогда вам не нужно
if
. Сортируйте числа и всегда используйте первый (наименьший):источник
Обычно я делаю подобные вещи со встроенным кодом Python:
источник
источник