tra-loi-cau-hoi-phat-trien-web.com

Làm thế nào để thực hiện các phép tính số nguyên & float, trong bash hoặc các ngôn ngữ / khung khác?

Sử dụng echo "20+5" Theo nghĩa đen sẽ tạo ra văn bản "20+5".

Tôi có thể sử dụng lệnh nào để lấy tổng số, 25 Trong trường hợp này?

Ngoài ra, cách dễ nhất để làm điều đó chỉ là sử dụng bash cho dấu phẩy động? Ví dụ: echo $((3224/3807.0)) print 0 :(.

Tôi đang tìm kiếm câu trả lời bằng chính lệnh cơ bản Shell ('dòng lệnh') hoặc thông qua việc sử dụng các ngôn ngữ có sẵn từ dòng lệnh.

316
Michael Durrant

Có rất nhiều lựa chọn!!!

Tóm lược

$ 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

Chi tiết

Vỏ ốc

Bạn có thể sử dụng mở rộng số học POSIX cho số nguyên số học echo "$((...))":

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

Khá di động (ash dash yash bash ksh93 lksh zsh):
[.__.] Sử dụng khả năng printf để in float, chúng ta có thể mở rộng hầu hết các shell để thực hiện phép toán dấu phẩy động mặc dù trong phạm vi giới hạn (không quá 10 chữ số):

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

ksh93, yashzsh thực hiện hỗ trợ nổi tại đây:

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

chỉ ksh93 (trực tiếp) và zsh tải thư viện mathfunc tại đây:

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

(zsh cần tải zmodload zsh/mathfunc để nhận các hàm như atan).


Tương tác với zsh:

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

Với (t) csh (chỉ số nguyên):

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

Trong họ rc Shell, akanga là nhóm có mở rộng số học:

; echo $:25/3
8

Công cụ POSIX

bc (xem bên dưới để biết chế độ tương tác), hướng dẫn tại đây

Ghi nhớ: best calculator (mặc dù b trên thực tế là cơ bản).

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

(hỗ trợ số chính xác tùy ý)


chế độ tương tác 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

Rush là giải pháp, expr (không có chế độ tương tác):

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

Giải pháp của Joshua : awk (không có chế độ tương tác):

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

Các công cụ di động khác ít nhiều

Arcege là giải pháp, dc (chế độ tương tác: dc):

Điều đó thậm chí còn thú vị hơn vì nó hoạt động bằng ký hiệu đánh bóng ngược.

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

Nhưng không thực tế trừ khi bạn làm việc với ký hiệu đánh bóng ngược rất nhiều.

Lưu ý rằng dc có trước bcbc đã được triển khai trong lịch sử như một trình bao bọc xung quanh dc nhưng dc không được chuẩn hóa bởi POSIX


DQdims 's calc (bắt buộc Sudo apt-get install apcalc):

$ calc 2 + 4
6

Phiên dịch ngôn ngữ mục đích chung:

manatwork là giải pháp, node (chế độ tương tác: node; chức năng đầu ra không cần thiết):

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

Perl (chế độ tương tác: Perl -de 1):

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

Python (chế độ tương tác: python; không cần chức năng đầu ra):

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

Cũng hỗ trợ số chính xác tùy ý:

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

Nếu bạn đã cài đặt clisp, bạn cũng có thể sử dụng ký hiệu đánh bóng:

$ clisp -x "(+ 2 2)"

Marco là giải pháp, lua (chế độ tương tác: lua):

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

[~ # ~] php [~ # ~] (chế độ tương tác: php -a):

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

Ruby (chế độ tương tác: irb; không cần chức năng đầu ra):

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

Guile (chế độ tương tác: guile):

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

S-Lang (chế độ tương tác: slsh; hàm đầu ra không cần thiết, chỉ cần một dấu kết thúc ;):

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

Tcl (chế độ tương tác: tclsh; không cần chức năng đầu ra, nhưng expr is):

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

Shell shell:

$ 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
>

Nhiều SQL khác nhau:

SQLite (chế độ tương tác: 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

_Các tùy chọn trên mysql và postgres dừng hình ảnh 'nghệ thuật ascii'!

Các ngôn ngữ định hướng toán học chuyên ngành:

[~ # ~] r [~ # ~] ở chế độ đơn giản - cho phép tạo 1000 số ngẫu nhiên Bình thường và nhận được độ lệch chuẩn và in nó

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

[~ # ~] r [~ # ~] bằng cách sử dụng littler script - cho phép in pi bình phương

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

PARI/GP , một hệ thống đại số máy tính mở rộng cho lý thuyết số, đại số tuyến tính và nhiều thứ khác

$ 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 (ngôn ngữ được giải thích ở cấp độ cao, chủ yếu dành cho tính toán số)

Cũng hỗ trợ số phức:

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

Julia , ngôn ngữ và trình thông dịch hiệu suất cao cho tính toán khoa học và số.

Tùy chọn không tương tác:

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

Có nhiều cách để tính toán. Đối với các biểu thức đơn giản, bạn có thể sử dụng bash chính nó:

echo $((20+5))

hoặc expr:

expr 20 + 5

Và đối với các trường hợp phức tạp, có công cụ tuyệt vời bc:

echo "20+5" | bc

Btw, bc có thể tính toán biểu thức thậm chí rất phức tạp với rễ, logarit, cos, sin, v.v.

37
rush

Các giải pháp được đề cập là tốt cho các tính toán rất đơn giản, nhưng rất dễ bị lỗi. Ví dụ:

# 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

Một lỗi cú pháp như những cái cuối cùng dễ dàng được nhận thấy, nhưng các phản hồi số nguyên với phần nổi bị loại bỏ có thể dễ dàng không được chú ý và dẫn đến kết quả sai.

Đó là lý do tại sao tôi luôn sử dụng một ngôn ngữ kịch bản như Lua cho điều đó. Nhưng bạn có thể chọn bất kỳ ngôn ngữ kịch bản nào mà bạn quen thuộc. Tôi chỉ sử dụng Lua làm ví dụ. Những ưu điểm là

  • một cú pháp quen thuộc
  • chức năng quen thuộc
  • hãy cẩn thận
  • đầu vào linh hoạt
  • không gian thường không quan trọng
  • đầu ra điểm nổi

Ví dụ:

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

Chưa có ai nhắc đến awk?

Sử dụng các hàm POSIX Shell và sức mạnh toán học, chỉ cần xác định hàm (một dòng) này:

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

Sau đó, chỉ cần thực hiện những thứ như calc 1+1 hoặc là calc 5/2

Lưu ý: Để làm cho hàm luôn khả dụng, hãy thêm nó vào ~/.bashrc (hoặc tệp khởi động Shell tương ứng của bạn)

Tất nhiên, một tập lệnh nhỏ có tên "calc" với nội dung sau:

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

cũng có thể làm việc.

25
Joshua

Bạn có thể sử dụng bc. Ví dụ.,

$ echo "25 + 5" | bc
30

Hoặc bc <<< 25+5 cũng sẽ làm việc.

Hoặc tương tác, nếu bạn muốn làm nhiều hơn chỉ là một phép tính đơn giản:

$ 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

Việc thực hiện GNU của bc in thông tin tiêu đề/bản quyền đó khi khởi động khi cả stdin và stdout của nó đi đến một thiết bị đầu cuối. Bạn có thể chặn nó bằng (cụ thể GNU ) -q Lựa chọn. Để biết thêm thông tin, hãy xem trang bc man

18
Levon

Bạn có thể sử dụng calc:

Nếu bạn chỉ nhập calc mà không có đối số nào khác, nó sẽ vào chế độ tương tác nơi bạn có thể tiếp tục làm toán. Bạn thoát cái này bằng cách gõ 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

Hoặc bạn sử dụng nó với biểu thức làm đối số và nó sẽ cung cấp câu trả lời và sau đó thoát

$calc 2 + 4
    6
$

calc tương tự như bc, tôi chỉ thích cách nó hoạt động như mặc định tốt hơn

17
DQdlM

Tôi thích kích hoạt Python và sử dụng nó như một máy tính tương tác (nhưng sau đó, tôi lại là một Python).

10
asmeurer

Vì không ai khác đã đề cập đến nó, và mặc dù nó không hoàn toàn là một máy tính (nhưng tất cả đều không phải là những ngôn ngữ kịch bản có mục đích chung này), tôi muốn đề cập đến units:

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

Hoặc, với đầu ra ít hơn để bạn chỉ có thể lấy số để sử dụng trong $() để gán cho thứ gì đó:

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

Và nó thậm chí còn chuyển đổi nhiệt độ

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

Để có được sự chuyển đổi nhiệt độ trong một biểu thức để tính toán thêm, hãy làm điều này:

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

Đối với số học Integer (trong đó 3/2 = 1)

  • bashecho $(( 1+1 ))
  • fishmath 1+1
  • zsh*echo $((1+1))

*: và ksh93, yash

Đối với số học dấu phẩy động (trong đó 3/2 = 1,5)

  • bashawk "BEGIN {print 10/3}" (độ chính xác thấp)
  • bashecho "10/3"|bc -l (độ chính xác cao)
  • fishmath -s4 10/3
  • zsh*echo $((10./3))

*: và ksh93, yash

Tất nhiên, bạn có thể định cấu hình Shell của mình để sử dụng awk với cách gõ tối thiểu như calc 10/3 (Xem ghi chú về cách thực hiện cho bash1 và cá2).

Lý do chính để đề xuất awk cho bash là vì nó được cài đặt sẵn trên hầu hết các hệ điều hành giống Unix và khá nhẹ (tất nhiên là có chi phí bắt đầu một quy trình) với đầu ra ít chính xác hơn nhưng thân thiện với con người hơn bc -l in 20 chữ số thập phân (mặc dù bạn chắc chắn có thể Tweak awk để có thêm chữ số thập phân ).


Ghi chú

(1) Cách sử dụng cú pháp đơn giản hóa trong bash

Thêm hàm bash này vào ~/.bashrc:

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

(2) Cách sử dụng cú pháp đơn giản hóa trong cá

Tạo hàm calc fish (nghĩa là tệp văn bản có tên /home/ndemou/.config/fish/functions/calc.fish):

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

Ngoài ra ghci, đó là Trình biên dịch Glasgow-Haskell trong chế độ tương tác (ghc --interactive, trái ngược với nó đánh giá một biểu thức với -e ), tạo nên một "máy tính" hấp dẫn:

$>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

Tôi sử dụng một tập lệnh python sẽ đánh giá biểu thức a python và in kết quả, sau đó tôi có thể chạy một cái gì đó như

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

kịch bản là:

#!/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')

Thật không may, tôi không nhớ nơi tôi đã mượn hầu hết các mã từ đó, vì vậy tôi không thể trích dẫn nó.

4
cobbal

Gnuplot

gnuplot - một chương trình vẽ đồ thị tương tác
[.__.] Thực hiện theo liên kết trên hoặc nhập gnuplot tạo thành Lời nhắc sau đó help bên trong trình thông dịch gnuplot .
[.__.] Gnuplot là một chương trình sinh ra để vẽ dữ liệu, nhưng cũng có thể được sử dụng để tính toán. Nó cung cấp lợi thế là bạn có thể xác định các hàm và sử dụng các hàm tích hợp.

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

Root (hoặc một số trình thông dịch C C khác )

hệ thống ROOT cung cấp một bộ OO khung với tất cả các chức năng cần thiết để xử lý và phân tích lượng lớn dữ liệu trong rất cách hiệu quả ...

Bạn có thể sử dụng nó như Trình thông dịch C , [~ # ~] cint [~ # ~] hoặc bạn có thể sử dụng một trong nhiều trình thông dịch C khác . IMHO, nó rất lớn, phức tạp, mạnh mẽ và không phải lúc nào cũng thân thiện nhưng cũng có thể mang lại sự hài lòng lớn.

Nếu bạn thực sự không muốn nghe giọng nói nhỏ bên trong bạn mà trích dẫn Confucio và bạn đã sẵn sàng để phá vỡ một (bơ) bay trên bánh xe bạn có thể sử dụng root . Trong trường hợp này -l là bắt buộc để tránh hiển thị màn hình giật gân ...

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

Tôi không thể tin được để đọc "sức mạnh của JavaScript" (nhưng tôi đã phải đưa ra câu trả lời cho các phần khác, ngoại trừ Perl tất nhiên.

Thực tế, đối với các trường hợp đơn giản là số học số nguyên là đủ, tôi sử dụng buildin $ ((...)) và giới thiệu nó. Khác, trong hầu hết các trường hợp tiếng vang "..." | bc là đủ.

Đối với một số hoạt động số học như thống kê, hoạt động ma trận và hơn thế nữa R là công cụ tốt hơn:

echo 25 + 5 | R --Vanilla

và đối với các bộ dữ liệu nhỏ và kết quả đồ họa vứt đi, oocalc là một tiện ích Nice.

4
user unknown

Để tính toán bàn điều khiển, tôi sử dụng concalc. (Sudo aptitude install concalc)

Sau đó, chỉ cần gõ concalc và nhấn enter. Nó sẽ không cung cấp Lời nhắc, nhưng chỉ cần nhập vào phép tính của bạn (không có dấu cách) và nhấn enter, và trên dòng tiếp theo, nó sẽ cung cấp cho bạn giá trị số.

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

Sử dụng GNU Nhiều thư viện số học chính xác thông qua chương trình run-expr Được cung cấp:

  • Tải xuống và giải nén (bạn sẽ cần lzip): tar -xvf gmp-5.1.3.tar.lz
  • Trong thư mục trên cùng, ./configuremake (không cần cài đặt)
  • Trong các bản demo/expr, make run-expr
  • Tôi muốn tạo một liên kết tượng trưng cho nó trong thư mục ~/bin Của tôi: ln -s /path/to/gmp/demos/expr/run-expr ~/bin/run-expr
  • Thêm một bí danh để dễ sử dụng; ví dụ alias calcf='run-expr -f' để đánh giá điểm nổi

Đầu ra:

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

Từ tệp 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.

Xem thủ công để biết các khác biệt và chi tiết về lớp chức năng.

2
user44370

Phần còn lại của các giải pháp ở đây đều có nhược điểm đáng chú ý.

Vì vậy, tôi đã tạo ra một lệnh mới để có thể làm điều này theo cách đơn giản và đáng tin cậy nhất.

Mẫu:

$ 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