it-swarm-ru.tech

Как делать целочисленные и плавающие вычисления в bash или других языках / фреймворках?

Использование echo "20+5" Буквально создает текст "20+5".

Какую команду я могу использовать, чтобы получить числовую сумму, 25 В этом случае?

Кроме того, каков самый простой способ сделать это, просто используя bash для чисел с плавающей запятой? Например, echo $((3224/3807.0)) печатает 0 :(.

Я ищу ответы, используя либо саму базовую командную оболочку ("командную строку"), либо используя языки, доступные из командной строки.

316
Michael Durrant

Вариантов много !!!

Резюме

_$ printf %.10f\\n "$((10**9 * 20/7))e-9"   # many shells. Not mksh.
$ echo "$((20.0/7))"                       # (ksh93/zsh/yash, not bash)
$ awk "BEGIN {print (20+5)/2}"
$ zcalc
$ bc <<< 20+5/2
$ bc <<< "scale=4; (20+5)/2"
$ dc <<< "4 k 20 5 + 2 / p"
$ expr 20 + 5
$ calc 2 + 4
$ node -pe 20+5/2  # Uses the power of JavaScript, e.g. : node -pe 20+5/Math.PI
$ echo 20 5 2 / + p | dc 
$ echo 4 k 20 5 2 / + p | dc 
$ Perl -E "say 20+5/2"
$ python -c "print(20+5/2)"
$ python -c "print(20+5/2.0)"
$ clisp -x "(+ 2 2)"
$ lua -e "print(20+5/2)"
$ php -r 'echo 20+5/2;'
$ Ruby -e 'p 20+5/2'
$ Ruby -e 'p 20+5/2.0'
$ guile -c '(display (+ 20 (/ 5 2)))'
$ guile -c '(display (+ 20 (/ 5 2.0)))'
$ slsh -e 'printf("%f",20+5/2)'
$ slsh -e 'printf("%f",20+5/2.0)'
$ tclsh <<< 'puts [expr 20+5/2]'
$ tclsh <<< 'puts [expr 20+5/2.0]'
$ sqlite3 <<< 'select 20+5/2;'
$ sqlite3 <<< 'select 20+5/2.0;'
$ echo 'select 1 + 1;' | sqlite3 
$ psql -tAc 'select 1+1'
$ R -q -e 'print(sd(rnorm(1000)))'
$ r -e 'cat(pi^2, "\n")'
$ r -e 'print(sum(1:100))'
$ smjs
$ jspl
_

Подробности

Ракушки

Вы можете использовать арифметическое расширение POSIX для целое число арифметическое echo "$((...))":

_$ echo "$((20+5))"
25
$ echo "$((20+5/2))"
22
_

Довольно переносимый ( _ash dash yash bash ksh93 lksh zsh_ ):
Используя функцию printf для печати чисел с плавающей запятой, мы можем расширить большинство оболочек для выполнения математических операций с плавающей запятой, хотя и с ограниченным диапазоном (не более 10 цифр):

_$ printf %.10f\\n "$((1000000000 *   20/7  ))e-9"
2.8571428570
_

_ksh93_ , yash и zsh здесь поддерживают поплавки:

_$ echo "$((1.2 / 3))"
0.4
_

только _ksh93_ (напрямую) и zsh загрузка библиотеки mathfunc здесь:

_$ echo "$((4*atan(1)))"
3.14159265358979324
_

(zsh нужно загрузить _zmodload zsh/mathfunc_, чтобы получить такие функции, как atan).


Интерактивно с Zsh:

_$ autoload zcalc
$ zcalc
1> PI/2
1.5708
2> cos($1)
6.12323e-17
3> :sci 12
6.12323399574e-17
_

С (t) csh (только целое число):

_% @ a=25 / 3; echo $a
8
_

В семействе оболочек rcakanga - это арифметическое расширение:

_; echo $:25/3
8
_

POSIX Toolchest

bc (интерактивный режим см. ниже), здесь руководство

Мнемоника: bстандартное восточное время calculator (хотя b на самом деле для basic).

_$ echo 20+5/2 | bc
22
$ echo 'scale=4;20+5/2' | bc
22.5000
_

(поддерживает произвольные числа точности)


интерактивный режим:

_$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
5+5
10

2.2+3.3
5.5
_

Rush решение, expr (без интерактивного режима):

_$ expr 20 + 5
25
$ expr 20 + 5 / 2
22
_

решение Джошуа : awk (без интерактивного режима):

_$ calc() { awk "BEGIN{print $*}"; }
$ calc 1/3
0.333333
_

Другие более или менее портативные инструменты

Arcege решение, dc (интерактивный режим: dc):

Который еще более забавен, так как это работает обратной польской нотацией.

_$ echo 20 5 2 / + p | dc 
22
$ echo 4 k 20 5 2 / + p | dc 
22.5000
_

Но не так практично, если вы не много работаете с обратной польской нотацией.

Обратите внимание, что dc предшествует bc и ​​bc исторически реализовывалось как оболочка вокруг dc, но dc не было стандартизировано POSIX


DQdims 's calc (обязательно _Sudo apt-get install apcalc)_:

_$ calc 2 + 4
6
_

Языковые переводчики общего назначения:

manatwork решение, node (интерактивный режим: node; функция вывода не необходимо):

_$ node -pe 20+5/2  # Uses the power of JavaScript, e.g. : node -pe 20+5/Math.PI
22.5
_

Perl (интерактивный режим: _Perl -de 1_):

_$ Perl -E "say 20+5/2"
22.5
_

Python (интерактивный режим: python; функция вывода не требуется):

_$ python -c "print(20+5/2)"
22 # 22.5 with python3
$ python -c "print(20+5/2.0)"
22.5
_

Также поддерживает произвольные числа точности:

_$ python -c 'print(2**1234)'
295811224608098629060044695716103590786339687135372992239556207050657350796238924261053837248378050186443647759070955993120820899330381760937027212482840944941362110665443775183495726811929203861182015218323892077355983393191208928867652655993602487903113708549402668624521100611794270340232766099317098048887493809023127398253860618772619035009883272941129544640111837184
_

Если у вас установлена ​​clisp, вы также можете использовать польскую запись:

_$ clisp -x "(+ 2 2)"
_

Marco решение, lua (интерактивный режим: lua):

_$ lua -e "print(20+5/2)"
22.5
_

[~ # ~] php [~ # ~] (интерактивный режим: _php -a_):

_$ php -r 'echo 20+5/2;'
22.5
_

Ruby (интерактивный режим: irb; функция вывода не требуется):

_$ Ruby -e 'p 20+5/2'
22
$ Ruby -e 'p 20+5/2.0'
22.5
_

Guile (интерактивный режим: guile):

_$ guile -c '(display (+ 20 (/ 5 2)))'
45/2
$ guile -c '(display (+ 20 (/ 5 2.0)))'
22.5
_

S-Lang (интерактивный режим: slsh; функция вывода не требуется, только терминатор _;_):

_$ slsh -e 'printf("%f",20+5/2)'
22.000000
$ slsh -e 'printf("%f",20+5/2.0)'
22.500000
_

Tcl (интерактивный режим: tclsh; функция вывода не нужна, но expr есть):

_$ tclsh <<< 'puts [expr 20+5/2]'
22
$ tclsh <<< 'puts [expr 20+5/2.0]'
22.5
_

Javascript оболочки:

_$ smjs
js> 25/3
8.333333333333334
js>

$ jspl
JSC: 25/3

RP: 8.33333333333333
RJS: [object Number]
JSC:
Good bye...

$ node
> 25/3
8.333333333333334
>
_

Различные SQL:

SQLite (интерактивный режим: _sqlite3_):

_$ sqlite3 <<< 'select 20+5/2;'
22
$ sqlite3 <<< 'select 20+5/2.0;'
22.5
_

MySQL :

_mysql -BNe 'select 1+1'
_

PostgreSQL :

_psql -tAc 'select 1+1
_

Опции на mysql и postgres останавливают образ "ascii art"!

Специализированные математические языки:

[~ # ~] r [~ # ~] в обычном режиме - позволяет сгенерировать 1000 нормальных случайных чисел, получить стандартное отклонение и распечатать его

_$ R -q -e 'print(sd(rnorm(1000)))'
> print(sd(rnorm(1000)))
[1] 1.031997
_

[~ # ~] r [~ # ~] с помощью литтлера скрипт - позволяет печатать пи в квадрате

_$ r -e 'cat(pi^2, "\n")'
9.869604
$  r -e 'print(sum(1:100))'
[1] 5050
_

PARI/GP , обширная система компьютерной алгебры для теории чисел, линейной алгебры и многих других

_$ echo "prime(1000)"|gp -q
7919                        // the 1000th prime
$ echo "factor(1000)" | gp -q
[2 3]
[5 3]                       // 2^3*5^3
$ echo "sum(x=1,5,x)" | gp -q
15                          // 1+2+3+4+5
_

GNU Octave (интерпретируемый язык высокого уровня, в основном предназначенный для численных вычислений)

Также поддерживает комплексные числа:

_$ octave
>> 1.2 / 7
ans =  0.17143
>> sqrt(-1)
ans =  0 + 1i
_

Юлия , высокопроизводительный язык и переводчик для научных и численных вычислений.

Неинтерактивная опция:

_$ Julia -E '2.5+3.7'
6.2
_
431
lgarzo

Есть много способов для расчета. Для простых выражений вы можете использовать bash:

echo $((20+5))

или expr:

expr 20 + 5

А для сложных случаев есть отличный инструмент bc:

echo "20+5" | bc

Кстати, bc может вычислить даже очень сложное выражение с корнями, логарифмами, cos, sin и так далее.

37
rush

Упомянутые решения хороши для очень простых вычислений, но очень подвержены ошибкам. Примеры:

# without spaces expr 20+5 produces literally 20+5
expr 20+5
→ 20+5

# bc's result doesn't give the fractional part by default
bc <<< 9.0/2.0
→ 4

# expr does only integer
expr 9 / 2
→ 4

# same for POSIX arithmetic expansion
echo $((9/2))
→ 4

# bash arithmetic expansion chokes on floats
echo $((9.0/2.0))
→ bash: 9/2.0: syntax error: invalid arithmetic operator (error token is ".0")

# Most `expr` implementations also have problems with floats
expr 9.0 / 2.0
→ expr: non-integer argument

Синтаксическая ошибка, подобная последней, легко заметна, но целочисленные ответы с отброшенной частью с плавающей запятой могут легко остаться незамеченными и привести к неверным результатам.

Вот почему я всегда использую язык сценариев, например, Lua. Но вы можете выбрать любой язык сценариев, который вам знаком. Я просто использую Lua в качестве примера. Преимущества

  • знакомый синтаксис
  • знакомые функции
  • знакомые предостережения
  • гибкий ввод
  • пробелы обычно не имеют значения
  • вывод с плавающей запятой

Примеры:

lua -e "print(9/2)"
→ 4.5

lua -e "print(9 / 2)"
→ 4.5

lua -e "print(9.0/2)"
→ 4.5

lua -e "print (9 /2.)"
→ 4.5

lua -e "print(math.sqrt(9))"
→ 3
25
Marco

Никто еще не упомянул awk?

Используя функции POSIX Shell и awk math power, просто определите эту (одну строку) функцию:

calc(){ awk "BEGIN { print $*}"; }

Затем просто выполните такие вещи, как calc 1+1 или calc 5/2

Примечание. Чтобы функция всегда была доступна, добавьте ее в ~/.bashrc (или в соответствующий файл запуска вашей оболочки)

Конечно, небольшой скрипт с именем "calc" со следующим содержанием:

#!/bin/sh -
awk "BEGIN { print $* }"

также может работать.

25
Joshua

Вы можете использовать bc. Например.,

$ echo "25 + 5" | bc
30

Альтернативно bc <<< 25+5 также будет работать.

Или в интерактивном режиме, если вы хотите сделать больше, чем просто один простой расчет:

$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
25 + 5
30

GNU реализация bc печатает эту информацию заголовка/авторского права при запуске, когда и его stdin, и stdout идут в терминал. Вы можете подавить его с помощью (специфичной для GNU) ) -q вариант. Для получения дополнительной информации см. справочная страница bc

18
Levon

Вы можете использовать calc:

Если вы просто введете calc без других аргументов, он перейдет в интерактивный режим, в котором вы можете просто продолжать заниматься математикой. Вы выходите из этого, набирая выход:

C-style arbitrary precision calculator (version 2.12.3.3)
Calc is open software. For license details type:  help copyright
[Type "exit" to exit, or "help" for help.]

; 2+4
6
; 3+5
8
; 3.4+5
8.4
; 2^4
16
; exit

Или вы используете его с выражением в качестве аргумента, и он даст ответ, а затем выйти

$calc 2 + 4
    6
$

calc похож на bc, мне просто нравится, как он ведет себя по умолчанию лучше

17
DQdlM

Мне нравится запускать Python и использовать его как интерактивный калькулятор (но опять же, я Python).

10
asmeurer

Поскольку никто другой не упомянул об этом, и хотя это не является строго калькулятором (но не все эти языки сценариев общего назначения), я хотел бы упомянуть units:

_$ units "1 + 1"
        Definition: 2
$ units "1 lb" "kg"
        * 0.45359237
         / 2.2046226
_

Или, для меньшего количества вывода, так что вы можете получить только число, используемое в $() для присвоения чего-либо:

_$ units -t "1 + 1"
2
$ units -t "1 lb" "kg"
0.4539237
_

И это даже делает преобразование температуры

_$ units -t "tempC(20)" "tempF"
68
_

Чтобы получить преобразование температуры в выражении для дальнейшего расчета, сделайте это:

_$ units -t "~tempF(tempC(20))+1"
68.1
_
10
Random832

Для целочисленной арифметики (где 3/2 = 1)

  • bashecho $(( 1+1 ))
  • fish _math 1+1_
  • _zsh*_ echo $((1+1))

*: и ksh93, yash

Для арифметики с плавающей точкой (где 3/2 = 1,5)

  • bash _awk "BEGIN {print 10/3}"_ (низкая точность)
  • bash _echo "10/3"|bc -l_ (высокая точность)
  • fish _math -s4 10/3_
  • _zsh*_ echo $((10./3))

*: и ksh93, yash

Конечно, вы можете настроить свою оболочку на использование awk с минимальным набором текста, например _calc 10/3_ (см. Примечания о том, как это сделать для bash1 и рыба2).

Основная причина использования awk для bash заключается в том, что он предустановлен почти на всех Unix-подобных ОС и является достаточно легким (конечно, это стоит затрат на запуск процесса) с менее точным, но более удобным для пользователя выводом, чем _bc -l_ который печатает 20 десятичных цифр (хотя вы, конечно, можете настроить awk, чтобы получить больше десятичных цифр ).


Ноты

(1) Как использовать упрощенный синтаксис в bash

Добавьте эту функцию bash к своему _~/.bashrc_:

_calc(){ awk "BEGIN { print $*}"; }
_

(2) Как использовать упрощенный синтаксис в рыбе

Создайте функцию calc fish (т. Е. Текстовый файл с именем _/home/ndemou/.config/fish/functions/calc.fish_):

_function calc
    awk "BEGIN{ print $argv }" ;
end
_
6
ndemou
$> ghc -e '20 + 5'
25
it :: Integer

Также ghci, то есть Glasgow-Haskell Compiler в интерактивном режиме (ghc --interactive, в отличие от вычисления выражения с -e ), делает для увлекательного "калькулятора":

$>ghci
GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> pi
3.141592653589793
Prelude> ceiling pi
4
Prelude> compare 1 2
LT
6

Я использую небольшой скрипт python), который оценит выражение python и напечатает результат, затем я могу запустить что-то вроде

$ pc '[i ** 2 for i in range(10)]'
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

скрипт такой:

#!/usr/local/bin/python3

import sys
import traceback
from codeop import CommandCompiler

compile = CommandCompiler()
filename = "<input>"
source = ' '.join(sys.argv[1:]) + '\n'

try:
    code = compile(source, filename) 
except (OverflowError, SyntaxError, ValueError):
    type, value, sys.last_traceback = sys.exc_info()
    sys.last_type = type
    sys.last_value = value
    if filename and type is SyntaxError:
        # Work hard to stuff the correct filename in the exception
        try:
            msg, (dummy_filename, lineno, offset, line) = value.args
        except ValueError:
            # Not the format we expect; leave it alone
            pass
        else:
            # Stuff in the right filename
            value = SyntaxError(msg, (filename, lineno, offset, line))
            sys.last_value = value
    lines = traceback.format_exception_only(type, value)
    print(''.join(lines))
else:
    if code:
        exec(code)
    else:
        print('incomplete')

К сожалению, я не помню, откуда я позаимствовал большую часть кода, поэтому не могу его процитировать.

4
cobbal

Gnuplot

gnuplot - интерактивная программа построения графиков
Перейдите по приведенной выше ссылке или введите gnuplot из подсказки, затем help внутри интерпретатора gnuplot .
Gnuplot - программа, созданная для построения графиков данных, но также может использоваться для расчетов. Преимущество в том, что вы можете определять функции и/или использовать встроенные.

echo  "pr 20+5/2"  |  gnuplot          #  Lazy-note `pr` instead of print
22                                     #  Integer calculation & result
echo  "pr 20.+5/2"  |  gnuplot         #  Lazy-note `pr` instead of print
22.0                                   #  Floating point result
echo  "pr sin(2*pi/3.)"  |  gnuplot    #  Some functions ...
0.866025403784439

Корневой (или какой-либо другой интерпретатор C )

ROOT system предоставляет набор OO платформ со всеми функциями, необходимыми для обработки и анализа больших объемов данных в очень эффективный способ ...

Вы можете использовать его как интерпретатор C , [~ # ~] cint [~ # ~] , или вы можете использовать один из много много других интерпретаторов C . ИМХО, он огромный, сложный, мощный, и не всегда дружелюбный, но тоже может доставить большое удовольствие.

Если вы действительно не хотите слушать тихий голос внутри себя, который цитирует Конфуцио и вы готовы сломать (масло) муху на колесе вы можете использовать root . В этом случае -l обязательно, чтобы не показывать заставку ...

echo  "20+5/2"   | root -l
(const int)22
echo  "20+5/2."  | root -l
(const double)2.25000000000000000e+01

echo  "cout<< 20+5/2 << endl;"   | root -l
22
4
Hastur

Я не могу поверить, что я читал "силу JavaScript" (но мне пришлось поднять ответ для других частей, кроме, конечно, Perl.

Практически, для простых случаев, когда целочисленной арифметики достаточно, я использую buildin $ ((...)) и рекомендую его. Иначе, почти во всех случаях эхо "..." | Bc достаточно.

Для некоторых арифметических операций, таких как статистика, матричные операции и другие, R - лучший инструмент:

echo 25 + 5 | R --Vanilla

а для небольших наборов данных и результатов графического отбрасывания oocalc - это утилита Nice.

4
user unknown

Для консольных расчетов я использую concalc. (Sudo aptitude install concalc)

После этого просто введите concalc и ​​нажмите ввод. Он не будет выдавать подсказку, а просто введите ваш расчет (без пробелов) и нажмите клавишу ввода, и на следующей строке он даст вам числовое значение.

3
killermist

SQLite:

echo 'select 1 + 1;' | sqlite3 

MySQL:

mysql -e 'select 1 + 1 from dual;'

PostgreSQL:

psql -c 'select 1 + 1 as sum;'
3
Vidul

Используйте GNU Multi-Precision Aрифметическую библиотеку через поставляемый run-expr программа:

  • Скачайте и распакуйте (вам понадобится lzip): tar -xvf gmp-5.1.3.tar.lz
  • В верхнем каталоге ./configure и ​​make (не нужно устанавливать)
  • В демонстрациях/expr, make run-expr
  • Мне нравится создавать символическую ссылку на него в моем ~/bin каталог: ln -s /path/to/gmp/demos/expr/run-expr ~/bin/run-expr
  • Добавьте псевдоним для легкого использования; например alias calcf='run-expr -f' для оценки с плавающей запятой

Вывод:

# calcf '2/3'
"2/3" base 0: result 0.666666666666666666667e0

От run-expr.c файл:

Usage: ./run-expr [-z] [-q] [-f] [-p prec] [-b base] expression...

   Evaluate each argument as a simple expression.  By default this is in mpz
   integers, but -q selects mpq or -f selects mpf.  For mpf the float
   precision can be set with -p.  In all cases the input base can be set
   with -b, or the default is "0" meaning decimal with "0x" allowed.

Смотрите руководство для различий классов функций и деталей.

2
user44370

Все остальные решения здесь имеют заметные недостатки.

Поэтому я создал новую команду, чтобы сделать это самым простым и надежным способом.

Образцы:

$ solve 1/5
0.2
$ solve 1.5+3.1
4.6
$ solve 1/1000000
1e-06
$ solve 7+2^3
15
$ solve "sqrt(8)"
2.82842712474619
$ solve 1/0
non solvable ????: 1/0
0
Alberto Salvia Novella