- 12.8. Команды выполнения математических операций
- Как округлить десятичные числа, используя bc в bash?
- 11 ответов
- Математика в BASH с помощью bc
- Использование bc для базовых операций:
- Округление результата
- Если же у Вас есть файл с набором математических операций
- Использование результата последней операции:
- Тригонометрические функции:
- Создание переменных на основе результатов вычислений:
- You May Also Enjoy
- Jenkins auth over AWS Cognito
- Copy the Jenkins job
- Установка nginx из исходников
- Уникальные IP адреса в access.log Apache
- Как округлить десятичные дроби, используя bc в bash?
- 12 ответов
- Округление разделенного числа в Bash
- 10 ответов
12.8. Команды выполнения математических операций
Разложение целого числа на простые множители.
Bash не в состоянии выполнять действия над числами с плавающей запятой и не содержит многих важных математических функций. К счастью существует bc.
Универсальная, выполняющая вычисления с произвольной точностью, утилита bc обладает некоторыми возможностями, характерными для языков программирования.
Синтаксис bc немного напоминает язык C.
Поскольку это утилита UNIX, то она может достаточно широко использоваться в сценариях на языке командной оболочки, в том числе и в конвейерной обработке данных.
Ниже приводится простой шаблон работы с утилитой bc в сценарии. Здесь используется прием подстановки команд.
Пример 12-32. Ежемесячные выплаты по займу
Пример 12-33. Перевод чисел из одной системы счисления в другую
Один из вариантов вызова bc — использование вложенного документа, внедряемого в блок с подстановкой команд. Это особенно актуально, когда сценарий должен передать bc значительный по объему список команд и аргументов.
Пример 12-34. Пример взаимодействия bc со «встроенным документом»
Пример 12-35. Вычисление числа «пи»
Утилита dc ( desk calculator) — это калькулятор, использующий «Обратную Польскую Нотацию», и ориентированный на работу со стеком.
Многие стараются избегать испоьзования dc, из-за непривычной формы записи операндов и операций. Однако, dc имеет и своих сторонников.
Пример 12-36. Преобразование чисел из десятичной в шестнадцатиричную систему счисления
Изучение страниц info dc позволит детальнее разобраться с утилитой. Однако, отряд «гуру», которые могут похвастать своим знанием этой мощной, но весьма запутанной утилиты, весьма немногочислен.
Пример 12-37. Разложение числа на простые множители
Еще один способ выполнения математических операций, над числами с плавающей запятой, состоит в создании сценария-обертки, использующего математические функции awk.
Пример 12-38. Расчет гипотенузы прямоугольного треугольника
Источник
Как округлить десятичные числа, используя bc в bash?
Быстрый пример того, что я хочу использовать сценарии bash:
Предполагая, что цена составляет: 48.86 Ответ будет следующим: 41.406779661 (41.40 фактически потому, что я использую scale=2; )
Мой вопрос: Как я обойду второй десяток, чтобы показать ответ таким образом ?: 41.41
11 ответов
Функция раунда bash:
Используется в вашем примере кода:
Самое простое решение:
Округление Bash /awk:
Если у вас есть python, вы можете использовать что-то вроде этого:
Вот чисто bc-решение. Правила округления: при +/- 0,5, округляются от нуля.
Поместите масштаб, который вы ищете, в $ result_scale; ваша математика должна быть там, где $ MATH находится в списке команд bc:
Я знаю, что это старый вопрос, но у меня есть чистое «bc’-решение без« if »или ветвей:
Используйте его как bcr ‘2/3’ 5 или bcr ‘0.666666’ 2 -> (выражение, за которым следует масштаб)
Это возможно, потому что в bc (например, C /C ++) разрешено смешивать логические выражения в ваших вычислениях. Выражение ((t>0)-(t будет оцениваться до +/- 0,5 в зависимости от знака ‘t’ и, следовательно, использовать правильное значение для округления.
Это на самом деле просто: нет необходимости явно добавлять жесткий код «-0,5» для отрицательных чисел. Математически говоря, мы просто вычислим абсолютное значение аргумента и еще добавим 0.5, как обычно. Но поскольку у нас (к сожалению) нет встроенной функции abs() (если мы ее не закодируем), мы просто отрицать аргумент, если он отрицательный.
Кроме того, очень сложно работать с параметром quotient как параметр (так как для моего решения я должен иметь возможность получить доступ к дивиденду и делителю отдельно). Вот почему мой скрипт имеет дополнительный третий параметр.
Я все еще ищу чистый bc ответ на вопрос, как объединить только одно значение внутри функции, но вот чистая —- +: = 1 =: + —- ответ:
В основном, это тщательно извлекает десятичные числа, умножает все на 100 миллиардов (10¹⁰, #!/bin/bash echo «Insert the price you want to calculate:» read float echo «This is the price without taxes:» embiggen() < local int precision if [ "$1" != "$<1#*.>» ]; then # there is a decimal point fraction=»$<1#*.>» # just the digits after the dot fi int=»$<1%.*>» # the float as a truncated integer precision=»$<#fraction>» # the number of fractional digits echo $(( 10**10 * $int$fraction / 10**$precision )) > # round down if negative if [ «$float» != «$
Функция bash присваивает усеченную целочисленную форму своего аргумента embiggen() и сохраняет числа после точки в $int . Число дробных цифр отмечено в $fraction . Математика умножает 10¹⁰ на конкатенацию $precision и $int , а затем настраивает это соответствие точности (например, $fraction становится 10¹⁰ × 4886/100 и возвращает embiggen 48.86 , что составляет 488 600 000 000).
Мы хотим получить окончательную точность сотых, поэтому умножим первое число на 100, добавим 5 для округления, а затем разделим второе число. Это присвоение 488600000000 оставляет нас в сто раз окончательный ответ.
Теперь нам нужно добавить десятичную точку. Мы присваиваем новый $answer значение $int за исключением последних двух цифр, затем $answer с точкой и echo , за исключением значения $answer , о котором уже позаботились. (Не обращайте внимания на ошибку подсветки синтаксиса, которая делает это похожим на комментарий)
(Башизм: возведение в степень не является POSIX, так что это базис. Чистое решение POSIX потребует, чтобы циклы добавляли нули, а не использовали десять. Кроме того, «embiggen» — это совершенно кромовое слово.)
Одна из основных причин, по которой я использую $int , поскольку моя оболочка — это то, что она поддерживает математику с плавающей запятой. Решение этого вопроса довольно просто в zsh :
(Мне бы хотелось, чтобы кто-то добавил комментарий к этому ответу с трюком, чтобы включить арифметику с плавающей запятой в printf %.2f $((float/1.18)) , но Я уверен, что такой функции еще не существует.)
Источник
Математика в BASH с помощью bc
bc — это язык, который поддерживает числа произвольной точности с интерактивным исполнения отчетности.
Безусловно, bc — один из аутсайдеров, когда дело доходит до расчетов по командной строке.
Главным достоинством bc является обработка чисел с запятой (float). В среде bash можно проводить обычные операции (сложение, вычитание, деление и умножение) с целыми числами, но без bc не обойтись, когда дело доходит до десятичных дробей.
Дальше приводится несколько примеров использования bc:
Использование bc для базовых операций:
как всегда, можно использовать echo + | :
bc , как положено, соблюдает приоритетность математических операций. Проверьте:
Округление результата
В случае выполнения операции деления из примера bc вернет 1. Для того что бы показать цифры после запятой нужно указать сколько их нужно с помощью scale (по умолчанию = 0):
Если же у Вас есть файл с набором математических операций
воспользуйтесь слудющей конструкцией:
Использование результата последней операции:
Вместо last можно использовать точку:
Получение квадратного корня и возведение в степень
sqrt вернет квадратный корень из числа. Если результат является десятичной дробью — используйте scale для отображения знаков после запятой.
Довольно странно, что у библиотеки, написанной на C не предусмотрено использование sqr, но все же его нету.
Пример возведения в степень:
Тригонометрические функции:
Сомневаюсь, что кто-то будет в скриптах использовать значение косинуса или натурального логарифма числа, но все же:
- s (x) Синус x. x задается в радианах.
- c (x) Косинус x. x задается в радианах.
- l (x) Натуральный логарифм x
Создание переменных на основе результатов вычислений:
В этой статье bc используется для определения места, которое занимают базы даных mysql.
Updated: January 27, 2015
You May Also Enjoy
Jenkins auth over AWS Cognito
Jenkins auth over AWS Cognito
Copy the Jenkins job
Copy the Jenkins job
Установка nginx из исходников
В разных случаях приходится компилировать ПО имея его исходники. Опять же хочу разводить демагогию на эту тему. Хочу рассказать как собрать nginx последней в.
Уникальные IP адреса в access.log Apache
Получить список уникальных IP адресов в лог файле вэбсервера Apache можно с помощью:
Источник
Как округлить десятичные дроби, используя bc в bash?
Быстрый пример того, что я хочу, используя bash-скриптинг:
Предполагая, что цена: 48,86 Ответ будет:41,406779661 (41,40 на самом деле, потому что я использую scale=2; )
My Question is: How I round the second decimal to show the answer in this way?:41.41
12 ответов
Функция bash round:
Используется в вашем примере кода:
Самое простое решение:
Если у вас есть Python, вы можете использовать что-то вроде этого:
Вот чисто до н.э. Правила округления: +/- 0,5, округление от нуля.
Поместите искомую шкалу в $result_scale; ваша математика должна быть там, где $MATH находится в списке команд bc:
Я знаю, что это старый вопрос, но у меня есть чистое ‘bc’ -решение без ‘if’ или ответвлений:
Используйте это как bcr ‘2/3’ 5 или же bcr ‘0.666666’ 2 -> (выражение сопровождается шкалой)
Это возможно, потому что в bc (например, C/C++) разрешено смешивать логические выражения в ваших вычислениях. Выражение ((t>0)-(t будет оцениваться до +/-0,5 в зависимости от знака ‘t’ и, следовательно, использовать правильное значение для округления.
Чистая реализация до н.э. согласно запросу
если вы поместите это в файл с именем functions.bc, то вы можете округлить с
echo ‘ceil(3.1415)’ | bc functions.bc
Мне пришлось рассчитать общую продолжительность коллекции аудиофайлов.
Поэтому мне пришлось:
A. получить продолжительность для каждого файла (не показан)
Б. сложить все продолжительности (они были каждый в NNN.NNNNNN (фп) секунд)
C. отдельные часы, минуты, секунды, секунды.
D. Выведите строку HR:MIN:SEC:FRAMES, где frame = 1/75 сек.
(Кадры взяты из кода SMPTE, используемого в студиях.)
A: использовать ffprobe и разобрать строку продолжительности в число fp (не показано)
Это на самом деле просто: нет необходимости явно добавлять жестко закодированный вариант «-0.5» для отрицательных чисел. Говоря математически, мы просто вычислим абсолютное значение аргумента и добавим 0.5, как обычно. Но так как у нас (к сожалению) нет встроенного abs() Функция в нашем распоряжении (если мы не кодируем один), мы просто будем отрицать аргумент, если он отрицательный.
Кроме того, оказалось очень громоздким работать с частным как параметром (так как для моего решения я должен иметь доступ к дивиденду и делителю отдельно). Вот почему мой сценарий имеет дополнительный третий параметр.
Вот сокращенная версия вашего скрипта, исправленная для предоставления желаемого результата:
Обратите внимание, что округление до ближайшего целого равнозначно добавлению.5 и получению слова или округлению вниз (для положительных чисел).
Кроме того, масштабный коэффициент применяется во время работы; так (это bc команды, вы можете вставить их в свой терминал):
Я все еще ищу чистый bc ответ, как округлить только одно значение в функции, но вот чистый bash ответ:
В основном, это тщательно извлекает десятичные дроби, умножает все на 100 миллиардов (10¹⁰, 10**10 в bash ), настраивает точность и округление, выполняет фактическое деление, делит обратно на соответствующую величину и затем вставляет десятичное число.
embiggen() Функция назначает усеченную целочисленную форму своего аргумента $int и сохраняет числа после точки в $fraction , Количество дробных цифр отмечено в $precision , Математика умножает 10¹⁰ на конкатенацию $int а также $fraction а затем корректирует это в соответствии с точностью (например, embiggen 48.86 становится 10¹⁰ × 4886 / 100 и возвращается 488600000000 что составляет 488 600 000 000).
Нам нужна конечная точность в сотых долях, поэтому мы умножаем первое число на 100, добавляем 5 для округления и затем делим второе число. Это назначение $answer оставляет нам в сто раз окончательный ответ.
Теперь нам нужно добавить десятичную точку. Мы назначаем новый $int значение для $answer исключая последние две цифры, затем echo это с точкой и $answer исключая $int значение, о котором уже позаботились. (Не берите в голову ошибку подсветки синтаксиса, которая заставляет это походить на комментарий)
(Bashism: возведение в степень не является POSIX, так что это bashism. Чистое решение POSIX потребовало бы циклов для добавления нулей, а не использования степеней десяти. Кроме того, «embiggen» — совершенно непонятное слово.)
Одна из главных причин, по которой я использую zsh поскольку моя оболочка в том, что она поддерживает математику с плавающей точкой Решение этого вопроса довольно простое в zsh :
(Я бы хотел, чтобы кто-то добавил комментарий к этому ответу с хитростью, чтобы включить арифметику с плавающей запятой в bash , но я уверен, что такой функции еще не существует.)
Источник
Округление разделенного числа в Bash
Как мне округлить результат из двух разделенных чисел, например
$ testOne содержит «1», хотя его следовало округлить до «2» в качестве ответа от 3/2 = 1,5.
10 ответов
Чтобы выполнить округление в арифметике с усечением, просто добавьте (denom-1) в числитель.
Пример округления в меньшую сторону:
Пример округления в большую сторону:
Чтобы выполнить округление до ближайшего, добавьте к числителю (denom/2) (половинки округляются в большую сторону):
Хорошее решение — получить ближайшее круглое число.
Логика проста, если десятичное значение var меньше 0,5, тогда ближайшим взятым значением будет целое число. Хорошо, если десятичное значение больше 0,5, тогда добавляется следующее целочисленное значение, а поскольку awk тогда принимает только целую часть. Проблема решена
Bash не даст вам правильный результат 3/2, так как он не выполняет математику с плавающей точкой. вы можете использовать такие инструменты, как awk
Или до нашей эры
Если у вас есть целочисленное деление положительных чисел, которое округляется до нуля, вы можете добавить к деленному на единицу меньше делителя, чтобы округлить его в большую сторону.
То есть замените X / Y на (X + Y — 1) / Y .
Случай 1: X = k * Y (X является целым числом, кратным Y): В этом случае у нас есть (k * Y + Y — 1) / Y , который разделяется на (k * Y) / Y + (Y — 1) / Y . Часть (Y — 1)/Y округляется до нуля, и остается частное от k . Это именно то, что мы хотим: когда входные данные делятся, мы хотим, чтобы скорректированный расчет по-прежнему давал правильное точное частное.
Случай 2: X = k * Y + m , где 0 (X не кратно Y). В этом случае у нас есть числитель k * Y + m + Y — 1 или k * Y + Y + m — 1 , и мы можем записать деление как (k * Y)/Y + Y/Y + (m — 1)/Y . Поскольку 0 , 0 и так последний член (m — 1)/Y обращается в ноль. У нас осталось (k * Y)/Y + Y/Y , которые работают до k + 1 . Это показывает, что поведение округляется. Если у нас есть X , которое является k кратным Y , если мы добавляем к нему только 1, деление округляется до k + 1 .
Но это округление прямо противоположно; все неточные деления удаляются с нуля. Как насчет чего-то среднего?
Этого можно добиться, «начав» числитель с помощью Y/2 . Вместо X/Y вычислите (X+Y/2)/Y . Вместо доказательства давайте рассмотрим это эмпирическим путем:
Всякий раз, когда делитель является четным положительным числом, если числитель сравним с половиной этого числа, он округляется в большую сторону и округляется в меньшую сторону, если оно на единицу меньше этого числа.
Например, round 6 12 переходит в 1 , как и все значения, которые равны 6 по модулю 12 , например 18 (который идет до 2) и скоро. round 5 12 опускается до 0 .
Для нечетных чисел поведение правильное. Ни одно из точных рациональных чисел не находится посередине между двумя последовательными кратными. Например, со знаменателем 11 мы имеем 5/11 ; и round 5 11 округляет в меньшую сторону, а round 6 11 округляет в большую сторону.
Чтобы округлить, вы можете использовать модуль.
Вторая часть уравнения прибавится к True, если останется остаток. (Истина = 1; Ложь = 0)
Учитывая значение с плавающей запятой, мы можем тривиально округлить его с помощью printf:
Или, чтобы использовать исходный запрос:
Если десятичным разделителем является запятая (например: LC_NUMERIC = fr_FR.UTF-8, см. здесь ):
Подмена нужна для решения ghostdog74:
Другое решение — выполнить разделение в команде python. Например:
Мне кажется менее архаичным, чем использование awk.
Источник