Если вы пользователь Linux, Free/Open BSD или другой свободной ОС, есть вероятность, что интерфейс командной строки вам не чужд. В таком случае можно использовать командную оболочку для простых арифметических действий. Для этого не нужно устанавливать дополнительных программ, все уже есть в базовом наборе операционной системы. Они позволяют качественно заменить привычный калькулятор на столике счетовода.
bash калькулятор целочисленный
Арифметические операции с целочисленными в bash
будут выглядеть так:
$((expression))
$(( n1+n2 ))
$(( n1/n2 ))
$(( n1*n2 ))
$(( n1-n2 ))
Например:
$ echo $((15+25))
$ 40
На man
странице bash
, в разделе ARITHMETIC EVALUATION
вы можете ознакомиться с приоритетом исполнения действий операторов. И, кстати, можно получить тот же результат, используя команду expr целочисленное выражение
, вместо подстановки с двойными скобками в командах вывода.
$ expr 15 + 25
$ 40
bc мэдскиллз
Целочисленные выражения это конечно хорошо, но как-то маловато даже для калькулятора. Благо в наборе есть еще bc
— Си-подобный интерактивный интерпретатор. Не будем тратить время на сложение и вычитание, перейдем сразу к более интересным занятиям.
$ echo 7^7 |bc
823543
Это уже получше калькулятора, так как позволяет получить любое количество чисел в дробной части с помощью переменной scale
. Остерегайтесь поддельных проприетарных версий bc
, так как они поддерживают всего-лишь 99 знаков после запятой!
$ echo 'scale=30;sqrt(2)' | bc
1.414213562373095048801688724209
Еще 2 важные переменные: ibase
и obase
указывают на основание входящих и исходящих чисел.
$ echo 'ibase=16;obase=A;FF' | bc
255
Тут, кстати, есть засада. Посмотрите на эти два примера. Вроде бы пытаешься сделать то же самое, но результат разный. Вся суть в том, что в первом примере ibase=2
, но сама obase=10
принимает значение 2 в силу того, что ibase
определяет по базе obase
и 10 становится равной 2. Чтобы разорвать этот круг, надо использовать hex.
$ echo 'ibase=2;obase=10;10' | bc
10
$ echo 'ibase=2;obase=A;10' | bc
2
При множественном возведении числа в степень важно расставить нужным образом скобки, ибо bc
правоассоциативна и результат может быть не тот, на который вы рассчитывали.
$ echo '4^4^4' |bc
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
$ echo '(4^4)^4' |bc
4294967296
Помимо этих художеств, bc
имеет еще интерактивный режим в котором пищит и все портит делает все то же самое, но уже напрямую, без конвейера. Ключ -q
нужен, чтобы подавить гнушное приветствие.
$ bc -q
4^4^4
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
quit
Замер производительности процессора с bc
Много лун назад на одном популярном англоязычном форуме, ныне покойном, предложили гениально простой способ нагреть проц и посчитать его скорость в попугаях.
time echo "scale=5000; 4*a(1)" | bc -l -q
Мы подгружаем в bc
математическую библиотеку опцией -l
и просим выдать число ? с точностью 5000 знаков после запятой. Мой результат вычисления на Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz
:
real 0m24.507s
user 0m24.490s
sys 0m0.000s
s (x) The sine of x, x is in radians.
c (x) The cosine of x, x is in radians.
a (x) The arctangent of x, arctangent returns radians.
l (x) The natural logarithm of x.
e (x) The exponential function of raising e to the value x.
j (n,x) The Bessel function of integer order n of x.
Скрипты bc
В bc
можно, если очень нужно, определять функции и запускать скрипты. Определение функции имеет следующий синтаксис:
define name ( parameters ) { newline
auto_list statement_list }
Определены условные операторы if
и else
, причем последний не обязательно использовать, а также заголовки цикла for
и while
. На Википедии можно просмотреть список математических операторов и сравнить с таковым в Си. А вот так выглядит расчет чисел Фибоначчи в bc
.
#!/usr/bin/bc -q
define fibo(n) {
if (x <= 2) return n;
a = 0;
b = 1;
for (i = 1; i < n; i++) {
c = a+b; a = b; b = c;
}
return c;
}
fibo(1000)
quit
Как ЯП bc
не взлетел, однако, в качестве настольного калькулятора он более чем хорош.
awk: арифмометр и гадалка
Мне не часто доводилось пользоваться awk
, поэтому каждый раз я с удивлением обнаруживаю новые возможности этой программы. Если нужно посчитать логарифмы или синусы, не спешите паниковать, man awk
вам поможет. Вот так мы получили квадратный корень.
awk 'BEGIN{print sqrt(196)}'
14
А вот мы уже логарифмируем число ?, 5000 знаков которого мы уже вычисляли с помощью bc
.
awk 'BEGIN{print log(3.141592653589793238462643383279502884197169399375105820974944592307)}'
1.14473
Оглашаю полный список возможностей
atan2(y, x) Return the arctangent of y/x in radians.
cos(expr) Return the cosine of expr, which is in radians.
exp(expr) The exponential function.
int(expr) Truncate to integer.
log(expr) The natural logarithm function.
rand() Return a random number N, between 0 and 1, such that 0 ? N < 1.
sin(expr) Return the sine of expr, which is in radians.
sqrt(expr) Return the square root of expr.
srand([expr]) Use expr as the new seed for the random number generator. If no expr is provided, use the time of day. Return the previous seed for the random number generator.
Иногда, хочется довериться судьбе и послать все на три буквы — awk. Вообще-то, это пример из книги издательства O'Reilly, имитирует бросание монетки, выдавая 2 разных события пить или не пить с одинаковой вероятностью.
#!/bin/bash
ans=`awk -vmin=0 -vmax=1 'BEGIN{srand(); print int(min+rand()*(max-min+1))}'`
if [ $ans -eq 0 ]; then
echo "no"
else
echo "yes"
fi
В заключение
В нашей математической мастерской.еще очень много разных программ и если тема взлетит, попробуем перейти в первую и высшую лигу математического ПО с открытыми исходниками.
I. Замена калькулятора
- Встроенные средства командной оболочки: арифметические подстановки
bash
. - Программа
GNU bc
. - Неформат —
awk
.
II. Таблицы
OpenOffice / LibreOffice Calc
.- KDE
KSpread
. - GNOME
Gnumeric
. - Одиночные, например:
GNU Oleo
и другие.
III. Специализированные математические программы, уровень студент+
- GNU
Ocatve
. Scilab
.Maxima
.R
.Sage
.
IV. Языки программирования, математические библиотеки и среды
Ansi C
, библиотекиmath.h, complex.h, GSL
и другие товарищи.Java Scientific Library
Python
, библиотекиSciPy, NumPy, Sympy
и другие товарищи.COBOL
.Fortran
.Intel Math Kernel Library (Intel MKL)
AMD Accelerated Parallel Processing Math (APPLM)
AMD Core Math Library (ACML)
Список, естественно не полный, поэтому заранее прошу прощение, если не указал чей-то излюбленный математический пакет или ЯП. Последняя группа — поистине разливанное море разнообразного и годного софта.
А вот и обещанный мэдскиллз вместе с ответом на вопрос из картинки. Источник.
diff -u <(seq -f '%03.0f' 0 999) <((bc <<<'scale = 3009; 1 / 998001' | tr -d '\\\n'; echo) | sed s/.// | fold -3)
Комментарии (39)
LeonidZ
24.09.2016 06:37real 0m19.366s
user 0m19.337s
sys 0m0.024s
mbproMacBook Pro, i7 2.7 GHz, 16 Gb 1600 MHz DDR3
Но как бенчмарк не интересно: грузилось только 1 и 8 ядерwarlock13
24.09.2016 09:38+1При множественном возведении числа в степень важно расставить нужным образом скобки, а то программа сама решит как лучше группировать.
Чушь. Программа ничего не группирует, она просто делает то, что вы скажете. В следующем примере вы приказываете ей посчитать , и она так и делает.
ZyXI
24.09.2016 19:43-1В программе забит приоритет и ассоциативность операторов, что превращает
4^4^4
в4^(4^4)
. Такое вполне правильно считать «группировкой».warlock13
24.09.2016 20:09+3А ещё в программу заложены правила записи числ цифрами и сложения чисел. Значит ли это, что при сложении чисел важно правильно записать исходные числа (ну скажем, не вводить 3+3, если хочешь сложить 2 и 2), а то программа сама решит как лучше складывать числа?
ZyXI
24.09.2016 20:54Во всех случаях программа «сама решает» в соответствии с заложенными в неё правилами. Я отвечал на ваше «ничего не группирует» — ассоциативность операторов определяет группировку и говорить так не менее некорректно.
surefire
24.09.2016 10:01+1Из консоли считаю в node, просто запускаю и пишу выражение.
В gnome3 при установленном калькуляторе, можно считать прямо в строке поиска приложений.
Aineko
24.09.2016 10:05real 0m23.759s
user 0m23.547s
sys 0m0.016s
i5-2410M 2.30GHz
ubuntu bash on windows
janatem
24.09.2016 13:33+2echo 'ibase=2;obase=10;10' | bc
10Из общих соображений кажется естественным вначале задавать obase в привычной системе, потом ibase. Я так попробовал, и оно работает ожидаемым образом:
echo 'obase=10;ibase=2;10' | bc
2temujin
24.09.2016 23:42Класс!
$ echo 'ibase=2;obase=10;10' | bc $ 10 $ echo 'obase=10;ibase=2;10' | bc $ 2
janatem
25.09.2016 01:31Развращенный идеей функциональной чистоты, которая из первобытных функциональных языков проникла в почти во все современные, народ уже начал было забывать ужасы императивщины и потерял страх перед побочными эффектами.
ibase=2;obase=10;
— здесь мне тоже хочется увидеть такой смысл:
(ibase,obase)=(2,10)
но в тех присваиваниях притаился побочный эффект.
xenohunter
24.09.2016 14:20Для этого не нужно устанавливать дополнительных программ, все уже есть в базовом наборе операционной системы.
В Arch по умолчанию нет
bc
.
naething
24.09.2016 23:37+1Единственное, что в bc раздражает, — это скудность математической библиотеки. Например, возведение в дробную степень отсутствует:
$ echo '2^1.5' | bc -l
Runtime warning (func=(main), adr=9): non-zero scale in exponent
2
Приходится извращаться с помощью экспоненты и логарифма, что не очень удобно:
$ echo 'e(l(2)*1.5)' | bc -l
2.82842712474619009755
Или какой-нибудь арккосинус если нужно посчитать, приходится использовать арктангенс.
neit_kas
25.09.2016 06:01Виндовый CMD (а если точнее batch) тоже немного могёт в расчёты. Имеются: сложение, вычитание, умножение и деление (целочисленное, остаток подавляется). Например:
set /a result=15+25
echo %result%
Стоит отметить, если не в скриптах пилить, то результат выдаст и первая строчка. Кроме того, учитывая тот факт, что приличная часть народу на линуксах использует wine, то сей метод хоть и бессмыслен, но всё же имеет место быть.
Sabbaot
25.09.2016 19:29про bc рассказывается в книге «UNIX and Linux System Administration Handbook, 4th Edition» в вводной про сети. там же — про ipcalc, для расчета сетевых адресов и масок подсетей.
про GHCi выше уже сказали, познакомился, когда пытался в haskell
насчет таблиц и графиков, пользуем SigmaPlot
KawaiDesu
26.09.2016 14:54+1Использую calc (пакет в Ubuntu — apcalc, в Arch — calc). В отличии от bc имеет более очевидный синтаксис и терпим к нему (не нужно следить за пробелами между частами выражения, «25+ 4 -6» = 23), фактически может использоваться как скриптовой язык (!) через #!/usr/bin/calc. Жаль, его нет в дефолтной поставке.
А в раздел «математические среды», возможно, стоит добавить RStudio.
potan
26.09.2016 15:27-1В PowerShell арифметика в естественном виде доступна сразу. Я очень рад, что он портирован под Linux, очень удобно.
Сам все еще часто пользуюсь bc или ghci (когда надо что-то нетривиальное со строками или списками посчитать), реже awk, если попалась какая-то таблица, а дочку пытаюсь приучить к R (она сопротивляется и пользуется обычным микрокалькулятором, даже не программируемым).
catharsis
27.09.2016 16:16+1Пример с потерей числа интересный, спасибо.
Понадобилось какое-то время, чтобы понять, о чём речь и что к чему, особенно если пропустить ссылку на «источник» :)
saboteur_kiev
Бенчмарк на i7-5775c, линукс в виртуалбоксе на винде.
real 0m19.454s
user 0m19.420s
sys 0m0.000s
Антиоффтопик:
То есть, bc позволяет оперировать только от 2 до 16-ричной системы?
А есть простой способ переводить в произвольную систему, без программирования?
vlin
i5-4460 CPU @ 3.20GHz, ESXi 6, тест в двух виртуалках — Linux и FreeBSD
Примерно двукратная разница, результат расчета одинаков.
Наверное разные реализации bс, не думаю что от ОС так зависит.
Debian 8.2:
real 0m17.874s
user 0m17.796s
sys 0m0.000s
FreeBSD 10.3-RELEASE:
9.600u 0.047s 0:09.67 99.6% 40+167k 0+0io 0pf+0w
Danov
i7-4700, встроенный в Win10 Bash
real 0m15.492s
user 0m15.438s
sys 0m0.016s
Danov
уточню:
i7-4770 CPU @ 3.40GHz и загрузка лишь +14%.
Точно не про «нагреть проц»
G-M-A-X
Скорее всего, данный код однопоточный.
Запустите несколько потоков.
gromozeka1980
А есть простой способ переводить в произвольную систему, без программирования?
Есть. Делим с остатком на основание системы. Остаток записываем справа. С результатом повторяем операцию, пока число не кончится.
19 в двоичной
19/2=9, остаток 1
9/2=4, остаток 1
4/2 = 2, остаток 0
2/2 =1, остаток 0
1/2 = 0, остаток 1
записываем это всё справа-налево — 10011
19 в пятиричной
19/5 = 3, остаток 4
3/5 = 0, остаток 3
записываем справа-налево — 34
19 в 19-ричной
19/19 = 1, остаток 0
1/19 = 0, остаток 1
записываем справа-налево — 10
19 в любой системе с основанием больше 19
19/Основание = 0, остаток 19
считаем 19 буквами, (помним, что F — 15) получаем J
saboteur_kiev
Это не совсем простой, я думал что-то типа
echo «base=10; 12312313» | bc
Но без ограничений.
А тут все равно придется писать.
gromozeka1980
а, я протупил. я решил, что вы спрашиваете, как вручную переводить в любую систему :)
gromozeka1980
https://www.tools4noobs.com/online_tools/base_convert/
ZyXI
Zsh позволяет использовать любую систему счисления с целочисленными основаниями от 2 до 36:
Специально для 16?ричной системы работает префикс
0x
, для двоичной —0b
, других специальных префиксов нет (для 8?ричной можно включить обычный0755 == 493
, но по?умолчанию это отключено). Zsh также работает и с числами с плавающей точкой (но только в десятичной записи). Но zsh работает только с 64?битными целыми иdouble
, никакой длинной арифметики или чисел произвольной точности. Можно попросить zsh отделять каждые n разрядов, по?умолчанию 3: