如何在 bash 或其他语言/框架中进行整数和浮点计算?

Mic*_*ant 370 command-line shell arithmetic calculator floating-point

echo "20+5"从字面上使用会产生文本“ 20+5”。

25在这种情况下,我可以使用什么命令来获取数字总和?

另外,仅使用 bash 进行浮点运算的最简单方法是什么?例如,echo $((3224/3807.0))打印0:(.

我正在使用基本命令外壳(“命令行”)本身或通过使用命令行中可用的语言来寻找答案。

lga*_*rzo 515

有很多选择!!!

概括

$ printf %.10f\\n "$((10**9 * 20/7))e-9"   # many shells. Not mksh.
$ echo "$((20.0/7))"                       # (ksh93/zsh/yash, some 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
$ gs -q  <<< "5 2 div 20 add  ="
Run Code Online (Sandbox Code Playgroud)

细节

贝壳

您可以将 POSIX 算术扩展用于整数算术echo "$((...))"

$ echo "$((20+5))"
25
$ echo "$((20+5/2))"
22
Run Code Online (Sandbox Code Playgroud)

相当便携 ( ash dash yash bash ksh93 lksh zsh):
使用 printf 打印浮点数的能力,我们可以扩展大多数 shell 来进行浮点数学运算,尽管范围有限(不超过 10 位数字):

$ printf %.10f\\n "$((1000000000 *   20/7  ))e-9"
2.8571428570
Run Code Online (Sandbox Code Playgroud)

ksh93yashzsh在此处支持浮动:

$ echo "$((1.2 / 3))"
0.4
Run Code Online (Sandbox Code Playgroud)

ksh93(直接)并zsh在此处加载库 mathfunc:

$ echo "$((4*atan(1)))"
3.14159265358979324
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

使用 (t)csh(仅限整数):

% @ a=25 / 3; echo $a
8
Run Code Online (Sandbox Code Playgroud)

rcshell 系列中,akanga是具有算术扩展的:

; echo $:25/3
8
Run Code Online (Sandbox Code Playgroud)

POSIX 工具箱

bc(交互模式见下文),手册在这里

助记符:best calculator(虽然b实际上是为basic)。

$ echo 20+5/2 | bc
22
$ echo 'scale=4;20+5/2' | bc
22.5000
Run Code Online (Sandbox Code Playgroud)

(支持任意精度数)


bc交互模式:

$ 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
Run Code Online (Sandbox Code Playgroud)

Rush的解决方案,expr(无交互模式):

$ expr 20 + 5
25
$ expr 20 + 5 / 2
22
Run Code Online (Sandbox Code Playgroud)

约书亚的解决方案:(awk无交互模式):

$ calc() { awk "BEGIN{print $*}"; }
$ calc 1/3
0.333333
Run Code Online (Sandbox Code Playgroud)

其他或多或少的便携工具

Arcege的解决方案,dc(交互模式:)dc

这更有趣,因为它通过反向波兰符号工作。

$ echo 20 5 2 / + p | dc 
22
$ echo 4 k 20 5 2 / + p | dc 
22.5000
Run Code Online (Sandbox Code Playgroud)

但不是很实用,除非你经常使用反向抛光符号。

请注意,dc早于bcbc在历史上一直作为包装器实现,dcdc没有被 POSIX 标准化


DQdimscalc(必需的sudo apt-get install apcalc)

$ calc 2 + 4
6
Run Code Online (Sandbox Code Playgroud)

通用语言口译员:

manatwork的解决方案,node(交互模式:node;不需要输出功能):

$ node -pe 20+5/2  # Uses the power of JavaScript, e.g. : node -pe 20+5/Math.PI
22.5
Run Code Online (Sandbox Code Playgroud)

Perl(交互模式:)perl -de 1

$ perl -E "say 20+5/2"
22.5
Run Code Online (Sandbox Code Playgroud)

Python(交互模式:python;不需要输出函数):

$ python -c "print(20+5/2)"
22 # 22.5 with python3
$ python -c "print(20+5/2.0)"
22.5
Run Code Online (Sandbox Code Playgroud)

还支持任意精度数:

$ python -c 'print(2**1234)'
295811224608098629060044695716103590786339687135372992239556207050657350796238924261053837248378050186443647759070955993120820899330381760937027212482840944941362110665443775183495726811929203861182015218323892077355983393191208928867652655993602487903113708549402668624521100611794270340232766099317098048887493809023127398253860618772619035009883272941129544640111837184
Run Code Online (Sandbox Code Playgroud)

如果您已经clisp安装,您还可以使用波兰语表示法:

$ clisp -x "(+ 2 2)"
Run Code Online (Sandbox Code Playgroud)

Marco的解决方案,lua(交互模式:)lua

$ lua -e "print(20+5/2)"
22.5
Run Code Online (Sandbox Code Playgroud)

PHP(交互模式:)php -a

$ php -r 'echo 20+5/2;'
22.5
Run Code Online (Sandbox Code Playgroud)

Ruby(交互模式:irb;不需要输出函数):

$ ruby -e 'p 20+5/2'
22
$ ruby -e 'p 20+5/2.0'
22.5
Run Code Online (Sandbox Code Playgroud)

Guile(交互模式:)guile

$ guile -c '(display (+ 20 (/ 5 2)))'
45/2
$ guile -c '(display (+ 20 (/ 5 2.0)))'
22.5
Run Code Online (Sandbox Code Playgroud)

S-Lang(交互模式:slsh;不需要输出函数,只是一个;终结符):

$ slsh -e 'printf("%f",20+5/2)'
22.000000
$ slsh -e 'printf("%f",20+5/2.0)'
22.500000
Run Code Online (Sandbox Code Playgroud)

Tcl(交互模式:tclsh;不需要输出函数,但需要expr):

$ tclsh <<< 'puts [expr 20+5/2]'
22
$ tclsh <<< 'puts [expr 20+5/2.0]'
22.5
Run Code Online (Sandbox Code Playgroud)

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
>
Run Code Online (Sandbox Code Playgroud)

各种SQL:

SQLite(交互模式:)sqlite3

$ sqlite3 <<< 'select 20+5/2;'
22
$ sqlite3 <<< 'select 20+5/2.0;'
22.5
Run Code Online (Sandbox Code Playgroud)

MySQL

mysql -BNe 'select 1+1'
Run Code Online (Sandbox Code Playgroud)

PostgreSQL :

psql -tAc 'select 1+1
Run Code Online (Sandbox Code Playgroud)

_mysql 和 postgres 上的选项阻止了 'ascii art' 图像!

专门面向数学的语言:

普通模式下的R - 让我们生成 1000 个正常随机数并获得标准偏差并打印出来

$ R -q -e 'print(sd(rnorm(1000)))'
> print(sd(rnorm(1000)))
[1] 1.031997
Run Code Online (Sandbox Code Playgroud)

R使用littler脚本 - 让我们打印 pi 平方

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

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
Run Code Online (Sandbox Code Playgroud)

GNU Octave(一种高级解释语言,主要用于数值计算)

还支持复数:

$ octave
>> 1.2 / 7
ans =  0.17143
>> sqrt(-1)
ans =  0 + 1i
Run Code Online (Sandbox Code Playgroud)

Julia,用于科学和数值计算的高性能语言和解释器。

非交互式选项:

$ julia -E '2.5+3.7'
6.2
Run Code Online (Sandbox Code Playgroud)

GhostScript GhostScript 是一个 PostScript 解释器,即使在非常旧的发行版中也很常见。
有关支持的数学命令列表,请参阅PostScript 文档

互动示例:

$ GS_DEVICE=display gs
GPL Ghostscript 9.07 (2013-02-14)
Copyright (C) 2012 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>5 2 div 20 add  =
22.5
GS>
Run Code Online (Sandbox Code Playgroud)

  • 还有`dc`,它更有趣,因为它通过反向波兰符号工作。`回声 20 5 + p | dc` 但不太实用,除非你经常使用反向波兰语符号。 (4认同)
  • bc 很有趣:`whatis bc` -&gt; `一种任意精度的计算器语言` 有趣!谢谢! (3认同)
  • 作为 bc 方法的一种变体,我在我的 .bashrc 文件中添加了以下函数(我在 stackexchange 某处找到的)。我可以输入 calc 2+3 并得到 5。`## 命令行计算器 calc () { bc -l &lt;​​&lt;&lt; "$@" } ` (2认同)

rus*_*ush 41

有很多计算方法。对于简单的表达式,您可以使用bash它自己:

echo $((20+5))
Run Code Online (Sandbox Code Playgroud)

expr

expr 20 + 5
Run Code Online (Sandbox Code Playgroud)

对于复杂的情况,有很好的工具bc

echo "20+5" | bc
Run Code Online (Sandbox Code Playgroud)

顺便说一句,bc 甚至可以用根、对数、cos、sin 等计算非常复杂的表达式。

  • 您正在尝试执行 `expr 20+5`。您需要在数字和加号之间键入空格才能使其工作:`expr 20 + 5`。这很重要。 (3认同)

小智 31

还没有人提到 awk 吗?

使用 POSIX shell 函数和 awk 数学能力,只需定义这个(一行)函数:

calc(){ awk "BEGIN { print $*}"; }
Run Code Online (Sandbox Code Playgroud)

然后只需执行类似calc 1+1calc 5/2

注意:要使该功能始终可用,请将其添加到 ~/.bashrc (或您相应的 shell 的启动文件)

当然,还有一个名为“calc”的小脚本,内容如下:

#!/bin/sh -
awk "BEGIN { print $* }"
Run Code Online (Sandbox Code Playgroud)

也可以工作。

  • 哇这是最好的,甚至支持浮动。它无需安装任何东西即可工作! (2认同)

Mar*_*rco 28

上述解决方案适用于非常简单的计算,但非常容易出错。例子:

# 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
Run Code Online (Sandbox Code Playgroud)

像最后一个这样的语法错误很容易被注意到,但是带有丢弃的浮点部分的整数响应很容易被忽视并导致错误的结果。

这就是为什么我总是使用像 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
Run Code Online (Sandbox Code Playgroud)

  • 总是使用 `bc -l` 而不是普通的 `bc`,然后就不用担心 `scale`。 (8认同)
  • 就我个人而言,自从几年前我第一次遇到 `bc` 以来,我确实记得关于 `scale`。但是我总是忘记`lua`中的输出函数是`put`还是`puts`。;) (3认同)
  • `bc` 的结果不是整数,只是四舍五入到 `scale`,默认值为 0。所以如果你想要小数部分,`bc &lt;&lt;&lt; 'scale=4;9.0/2.0'`。 (2认同)

Lev*_*von 20

你可以使用bc. 例如,

$ echo "25 + 5" | bc
30
Run Code Online (Sandbox Code Playgroud)

或者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
Run Code Online (Sandbox Code Playgroud)

bc当标准输入和标准输出都进入终端时,GNU 实现会在启动时打印标题/版权信息。您可以使用(特定于 GNU 的)-q选项抑制它。有关更多信息,请参阅bc 手册页


DQd*_*dlM 20

您可以使用calc

如果您只输入calc没有其他参数,它会进入交互模式,您可以继续进行数学运算。您可以通过输入 exit 退出:

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
Run Code Online (Sandbox Code Playgroud)

或者您将它与表达式一起用作参数,它将提供答案然后退出

$calc 2 + 4
    6
$
Run Code Online (Sandbox Code Playgroud)

calc类似于bc,我只是喜欢它的默认行为方式更好


小智 12

我喜欢启动 Python 并将其用作交互式计算器(但话说回来,我是 Python 程序员)。


Ran*_*832 11

由于没有其他人提到它,虽然它不是严格的计算器(但也不是所有这些通用脚本语言),我想提一下units

$ units "1 + 1"
        Definition: 2
$ units "1 lb" "kg"
        * 0.45359237
         / 2.2046226
Run Code Online (Sandbox Code Playgroud)

或者,为了减少输出,您可以只获得$()用于分配某些内容的数字:

$ units -t "1 + 1"
2
$ units -t "1 lb" "kg"
0.4539237
Run Code Online (Sandbox Code Playgroud)

它甚至可以进行温度转换

$ units -t "tempC(20)" "tempF"
68
Run Code Online (Sandbox Code Playgroud)

要获得表达式中的温度转换以进行进一步计算,请执行以下操作:

$ units -t "~tempF(tempC(20))+1"
68.1
Run Code Online (Sandbox Code Playgroud)

  • 有太多不需要安装额外程序的选项,我不明白为什么有人会想要这样做。 (2认同)

ДМИ*_*КОВ 8

$> ghc -e '20 + 5'
25
it :: Integer
Run Code Online (Sandbox Code Playgroud)

此外ghci,这是交互式模式下的Glasgow-Haskell 编译器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
Run Code Online (Sandbox Code Playgroud)

  • 那`ghc` 是指格拉斯哥 Haskell 编译器吗? (3认同)

nde*_*mou 8

对于整数算术(其中 3/2=1)

  • bash echo $(( 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

您当然可以将您的 shell 配置为使用 awk 进行最少的输入calc 10/3(请参阅有关如何为 bash 1和 fish 2 执行此操作的说明)。

建议为 bash 使用 awk 的主要原因是它预装在几乎所有类 Unix 操作系统上,并且相当轻(当然有启动进程的成本),与bc -l打印 20 位十进制相比,输出不太精确但更人性化数字(尽管您当然可以调整 awk 以获得更多十进制数字)。


笔记

(1)如何在bash中使用简化语法

将此 bash 函数添加到您的~/.bashrc

calc(){ awk "BEGIN { print $*}"; }
Run Code Online (Sandbox Code Playgroud)

(2)如何在fish中使用简化语法

创建一个calcfish函数(即一个名为 的文本文件/home/ndemou/.config/fish/functions/calc.fish):

function calc
    awk "BEGIN{ print $argv }" ;
end
Run Code Online (Sandbox Code Playgroud)


Has*_*tur 6

Gnuplot

gnuplot - 一个交互式绘图程序
按照上面的链接或在gnuplot解释器中输入gnuplot提示。Gnuplot是一个为绘制数据而生的程序,但也可以用于计算。它提供的优势是您可以定义函数和/或使用内置函数。help

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
Run Code Online (Sandbox Code Playgroud)

根(或其他一些C 解释器

ROOT系统提供了一组与所有在一个非常有效的方式来处理和分析大量数据所需的功能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
Run Code Online (Sandbox Code Playgroud)


kil*_*ist 5

对于控制台计算,我使用concalc. ( sudo aptitude install concalc)

之后,只需键入concalc 并按回车键。它不会提供提示,而只是输入您的计算(无空格)并按回车键,然后在下一行,它会为您提供数值。


use*_*own 5

我不敢相信读到“JavaScript 的力量”(但我不得不为其他部分的答案投票,当然除了 perl。

实际上,对于整数算术足够的简单情况,我使用内置 $((...)) 并推荐它。否则,在几乎所有情况下 echo "..." | bc 就足够了。

对于一些算术运算,如统计、矩阵运算等,R是更好的工具:

echo 25 + 5 | R --vanilla
Run Code Online (Sandbox Code Playgroud)

对于小数据集和图形丢弃结果,oocalc是一个不错的实用程序。


cob*_*bal 5

我使用一个小的python脚本来评估一个python表达式并打印结果,然后我可以运行类似的东西

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

脚本是:

#!/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')
Run Code Online (Sandbox Code Playgroud)

不幸的是,我不记得我从哪里借用了大部分代码,所以我不能引用它。