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

<p>использование <code>echo "20+5"</code> буквально создает текст "<code>20+5</code>".</p><p>какую команду я могу использовать, чтобы получить числовую сумму, <code>25</code> в этом случае?</p><p>кроме того, каков самый простой способ сделать это, просто используя bash для чисел с плавающей запятой? например, <code>echo $((3224/3807.0)) печатает 0 :(.я ищу ответы, используя либо саму базовую командную оболочку ("командную строку"), либо используя языки, доступные из командной строки.

есть много способов для расчета. для простых выражений вы можете использовать bash:echo $((20+5)) </code></pre><p>или <code>expr</code>:</p><pre><code>expr 20 + 5 </code></pre><p>а для сложных случаев есть отличный инструмент <code>bc</code>:</p><pre><code>echo "20+5" | bc </code></pre><p>кстати, bc может вычислить даже очень сложное выражение с корнями, логарифмами, cos, sin и так далее.</p>

<p>упомянутые решения хороши для очень простых вычислений, но очень подвержены ошибкам. примеры:</p><pre><code># 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 </code></pre><p>синтаксическая ошибка, подобная последней, легко заметна, но целочисленные ответы с отброшенной частью с плавающей запятой могут легко остаться незамеченными и привести к неверным результатам.</p><p>вот почему я всегда использую язык сценариев, например, lua. но вы можете выбрать любой язык сценариев, который вам знаком. я просто использую lua в качестве примера. преимущества</p><ul> <li>знакомый синтаксис</li> <li>знакомые функции</li> <li>знакомые предостережения</li> <li>гибкий ввод</li> <li>пробелы обычно не имеют значения</li> <li>вывод с плавающей запятой</li> </ul><p>примеры:</p><pre><code>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 </code></pre>

<p>никто еще не упомянул awk?</p><p>используя функции posix shell и awk math power, просто определите эту (одну строку) функцию:</p><pre><code>calc(){ awk "begin { print $}"; } затем просто выполните такие вещи, как calc 1+1 или calc 5/2примечание. чтобы функция всегда была доступна, добавьте ее в ~/.bashrc (или в соответствующий файл запуска вашей оболочки)конечно, небольшой скрипт с именем "calc" со следующим содержанием:#!/bin/sh - awk "begin { print $* }" </code></pre><p>также может работать.</p>

<p>вы можете использовать <code>bc</code>. например.,</p><pre><code>$ 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 </code></pre><p>gnu реализация <code>bc</code> печатает эту информацию заголовка/авторского права при запуске, когда и его stdin, и stdout идут в терминал. вы можете подавить его с помощью (специфичной для gnu) ) <code>-q</code> вариант. для получения дополнительной информации см. <a href="http://linux.die.net/man/1/bc">справочная страница bc</a> </p>

<p>вы можете использовать <code>calc</code>:</p><p>если вы просто введете <code>calc</code> без других аргументов, он перейдет в интерактивный режим, в котором вы можете просто продолжать заниматься математикой. вы выходите из этого, набирая выход:</p><pre><code>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 </code></pre><p>или вы используете его с выражением в качестве аргумента, и он даст ответ, а затем выйти</p><pre><code>$calc 2 + 4 6 $ </code></pre><p><code>calc</code> похож на <code>bc</code>, мне просто нравится, как он ведет себя по умолчанию лучше</p>

<p>мне нравится запускать python и использовать его как интерактивный калькулятор (но опять же, я python).</p>

<p>поскольку никто другой не упомянул об этом, и хотя это не является строго калькулятором (но не все эти языки сценариев общего назначения), я хотел бы упомянуть <code>units</code>:</p><pre>\_<code>$ units "1 + 1" definition: 2 $ units "1 lb" "kg" * 0.45359237 / 2.2046226 </code>\_</pre><p>или, для меньшего количества вывода, так что вы можете получить только число, используемое в <code>$() для присвоения чего-либо:_$ units -t "1 + 1" 2 $ units -t "1 lb" "kg" 0.4539237 _и это даже делает преобразование температуры_$ units -t "tempc(20)" "tempf" 68 </code>\_</pre><p>чтобы получить преобразование температуры в выражении для дальнейшего расчета, сделайте это:</p><pre>\_<code>$ units -t "~tempf(tempc(20))+1" 68.1 _

для целочисленной арифметики (где 3/2 = 1) <strong> bash </strong> echo $(( 1+1 ))</code></li> <li><strong> <code>fish</code> </strong> \_<code>math 1+1</code>\_</li> <li><strong> \_<code>zsh*</code>\_ </strong> <code>echo $((1+1)) : и ksh93, yashдля арифметики с плавающей точкой (где 3/2 = 1,5) <strong> bash </strong> _awk "begin {print 10/3}"_  (низкая точность) <strong> bash </strong> _echo "10/3"|bc -l_  (высокая точность) <strong> fish </strong> _math -s4 10/3_ <strong> _zsh_ </strong> echo $((10./3))</code></li> </ul><p>*: и ksh93, yash</p><p>конечно, вы можете настроить свою оболочку на использование awk с минимальным набором текста, например \_<code>calc 10/3</code>\_ (см. примечания о том, как это сделать для bash<sup>1</sup> и рыба<sup>2</sup>).</p><p>основная причина использования awk для bash заключается в том, что он предустановлен почти на всех unix-подобных ос и является достаточно легким (конечно, это стоит затрат на запуск процесса) с менее точным, но более удобным для пользователя выводом, чем \_<code>bc -l</code>\_ который печатает 20 десятичных цифр (хотя вы, конечно, можете <a href="https://unix.stackexchange.com/questions/57006/awk-high-precision-arithmetic">настроить awk, чтобы получить больше десятичных цифр</a> ).</p><hr><h2>ноты</h2><h3>(1) как использовать упрощенный синтаксис в bash</h3><p>добавьте эту функцию bash к своему \_<code>~/.bashrc</code>\_:</p><pre>\_<code>calc(){ awk "begin { print $}"; } _(2) как использовать упрощенный синтаксис в рыбесоздайте функцию calc fish (т. е. текстовый файл с именем _/home/ndemou/.config/fish/functions/calc.fish_):_function calc awk "begin{ print $argv }" ; end </code>\_</pre>

<pre><code>$> ghc -e '20 + 5' 25 it :: integer также ghci, то есть <a href="https://www.haskell.org/haskellwiki/ghc/ghci"> glasgow-haskell compiler  в интерактивном режиме (ghc --interactive, в отличие от вычисления выражения с <a href="https://downloads.haskell.org/~ghc/7.0.1/docs/html/users_guide/modes.html">-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 </code></pre>

<p>я использую небольшой скрипт python), который оценит выражение python и напечатает результат, затем я могу запустить что-то вроде</p><pre><code>$ 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') к сожалению, я не помню, откуда я позаимствовал большую часть кода, поэтому не могу его процитировать.

gnuplot <a href="http://www.gnuplot.info/"> 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(2pi/3.)" | gnuplot # some functions ... 0.866025403784439 корневой (или какой-либо другой  интерпретатор c )<blockquote>  <a href="http://root.cern.ch/drupal/">root system предоставляет набор oo платформ со всеми функциями, необходимыми для обработки и анализа больших объемов данных в очень эффективный способ ...  </blockquote>вы можете использовать его как  интерпретатор c , <a href="http://root.cern.ch/drupal/content/cint"> [~ # ~] cint [~ # ~]  , или вы можете использовать один из <a href="https://stackoverflow.com/questions/584714/is-there-an-interpreter-for-c">много много других интерпретаторов c . имхо, он огромный, сложный, мощный, и не всегда дружелюбный, но тоже может доставить большое удовольствие.если вы действительно не хотите слушать тихий голос внутри себя, который цитирует <a href="http://thinkexist.com/quotation/never-use-a-cannon-to-kill-a-fly/365643.html">конфуцио и вы готовы <a href="https://english.stackexchange.com/a/100220"> сломать (масло) муху на колесе  вы можете использовать  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 

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

<strong>sqlite</strong>:echo 'select 1 + 1;' | sqlite3 <strong>mysql</strong>:mysql -e 'select 1 + 1 from dual;' <strong>postgresql</strong>:psql -c 'select 1 + 1 as sum;' 

используйте <a href="https://gmplib.org/"> 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. смотрите <a href="https://gmplib.org/manual/function-classes.html#function-classes">руководство для различий классов функций и деталей.

все остальные решения здесь имеют заметные недостатки.поэтому я создал новую команду, чтобы сделать это самым простым и надежным способом.образцы:$ 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 </code></pre><ul> <li> <a href="https://gitlab.com/es20490446e/solve">исходный код</a> </li> <li> <a href="https://bin.privacytools.io/?9f19a6db09ac510d#/c4xxo44o84ars6wlmvqek2sczxhcax1uep1qfmhdf0="> pkgbuild </a> </li> </ul>