Linux: работа с числами (bc, dc, expr)

http://www.basicallytech.com/blog/?/archives/23-command-line-calculations-using-bc.html  – примеры расчета простых выражений с помощью bc.

expr и let – базовые целочисленные калькуляторы. Поддерживают операции сложения/деления/умножения/вычитания.

EXPR
$ expr 6 + 2
8

$ expr 6 - 2
4

$ expr 6 \* 2
12

$ expr 6 / 2
3

$ expr 6 / 5
1

LET
let "b = $a * 2"
let "b = $a - 2"

bc (basic calculator) — интерактивный интерпретатор Си-подобного языка, позволяет выполнять вычисления с произвольно заданной точностью. Часто используется как калькулятор в командной строке UNIX-подобных операционных систем.

echo '57+43' | bc # addition
echo '57-43' | bc # subtraction
echo '57*43' | bc # multiplication

HEX/DEC/BIN CONVERSION (преобразование между системами счисления)

Можно использовать bc для конвертации между системами.
 
Между двоичной и десятичной.
> echo "ibase=2\n111"|bc
7

> echo "obase=2\n7"|bc
111
Между десятичной и шестнадцетиричной.
> echo 255 |dc -e "16o?p"
FF
> echo "ibase=16; FF" | bc
255

К примеру скрипт, который который конвертирует из десятичной в 16-тиричную полное число, потом разделяет шестнадцатиричные числа на две группы (одна с двумя символами – одним байтом, а вторая с четырьмя – двумя байтами) и конвертит группы раздельно обратно в шестнадцатиричную систему. Конвертация из десятичной в шестнадцатиричную делается через dc, обратно – через bc.

#!/usr/local/bin/bash

DEC=$1
HEX=$(echo $DEC |dc -e "16o?p")
HEX_SEPARATED_1=$(echo $HEX | sed 's/^\(.\{2\}\)/\1 /' | awk '{print $1}')
HEX_SEPARATED_2=$(echo $HEX | sed 's/^\(.\{2\}\)/\1 /' | awk '{print $2}')
DEC_SEPARATED_1=$(echo "ibase=16; $HEX_SEPARATED_1" | bc)
DEC_SEPARATED_2=$(echo "ibase=16; $HEX_SEPARATED_2" | bc)
echo "$DEC = $HEX = $DEC_SEPARATED_1/$DEC_SEPARATED_2"

IF numbers (float compare)

IF встроенный в bash умеет работать только с целыми числами. Для обхода этого ограничения следует использовать bc. К примеру, если нам нужно сравнить два числа с запятой, мы их сравниваем посредством bc, который выдает результат 1/0, а далее, посредством IF = 1 мы делаем то или иной действие. Использовал данную фичу в скрипте для сравнения полученного значения TX/RP-Power с эталонным.

Bash does not understand floating point arithmetic. It treats numbers containing a decimal point as strings.
$ echo "1.2 > 1.1" | bc
1

$ echo "1.2 > 1.3" | bc
0

COMPARE_RESULT_THROUGH_BC=$(echo "$TX_Power_mW > $TX_POWER_HIGH" | bc)
if [[ $COMPARE_RESULT_THROUGH_BC -eq 1 ]]; then
:some_code:
fi

Leave a Reply