Как правильно округлить числа IEEE 754 с плавающей запятой в командной строке?
Я хочу указать точность выходного числа - количество дробных цифр.
Округление 6.66
до точности 1
должно дать 6.7
, например. Больше в таблице ниже:
Value Precision Rounded
6.66 0 7
6.66 1 6.7
6.66 2 6.66
6.66 3 6.660
6.666 3 6.666
6.6666 3 6.667
Он должен использоваться в интерактивной оболочке, но в идеале достаточно надежный для использования в сценариях производственной оболочки.
bash
command-line
arithmetic
floating-point
Volker Siegel
источник
источник
awk
.Ответы:
Округление чисел с плавающей точкой
Что означает «округление числа с плавающей запятой»?
Это легко, очевидно ... Где моя математическая книга из школы ...
Нет, мы уже знаем, что ничего, связанного с числами с плавающей запятой, не так просто:
Для начала есть несколько режимов округления:
Как обращаться с угловыми корпусами? Как узнать, какие угловые случаи?
Хорошо, похоже, нам лучше использовать реализацию стандарта IEEE 754, и пусть наша система позаботится об этом.
Чтобы округлить число с плавающей запятой в оболочке на основе стандартной арифметики с плавающей запятой, нам нужно выполнить три шага:
Оказывается, что команда оболочки
printf
может сделать все это. Он может использоваться для печати чисел в соответствии со спецификацией формата, как описано вman 3 printf
. Числа округляются неявным образом стандартным способом, если это требуется для выходного формата:Команда
Округление
x
доp
точности цифр с вводом в качестве аргументов командной строки:Или в конвейере оболочки, с вводом
x
на стандартный ввод и вp
качестве аргумента:Примеры:
Плохие ловушки
Остерегайтесь локали! Он определяет разделитель между целой и дробной частью -
.
как вы можете ожидать.Но посмотрите сами, что происходит в немецком языке, например:
Да, все верно
6,667
- шесть запятых шесть шесть семь. Это наверняка испортит ваш сценарий.(Но только для двух клиентов в Германии. За исключением машин разработчика, отлаживающих в настоящее время для этих клиентов.)
Более надежный
Чтобы сделать его более надежным, используйте:
или
Это также использует
/usr/bin/printf
вместо встроенной оболочкиbash
илиzsh
для обхода незначительных несоответствий в реализацииprintf
вариантов и предотвращает очень грязный эффект, когда в немецком языкеLC_ALL
установлен, но не экспортирован. Затем встроенный использует,
и/usr/bin/printf
использует.
...См. Также
%g
для округления до указанного числа значащих цифр.источник
Следующее сработало для меня.
источник