跳轉到內容

Unix 指南/解釋/bc

來自華夏公益教科書

bc 是一種任意精度十進位制計算器語言。任意精度意味著數字可以在小數點前包含任意數量的數字,受記憶體限制;大多數其他語言將數字限制為最多八個位元組。小數點後的數字預設情況下為零,但可以設定為一個稱為“scale”的固定數量。

“bc”通常使用“-l”選項呼叫。該選項載入標準庫,其中包含大部分作為單個字母提供的三角函式,並將除法的十進位制位數設定為 20。

bc 概覽

echo '2*17' | bc                  # Feeds the math expression into bc, resulting in 34
echo '2^5' | bc                   # Exponentiation
echo '2+3;4*5' | bc               # Two calculations, output on separate lines
echo '1/3' | bc                   # Zero: the default decimal precision is 0
echo '1/3' | bc -l                # 0.33...: -l raises the decimal precision to 20
echo 'sqrt(2)' | bc -l
echo 'sqrt(2.00)' | bc            # 1.41; sqrt is affected by the argument precision
echo 's(1/3)' | bc -l             # sin(1/3): sin is there via -l loading the library
echo 's(1)+c(1)+a(1)+l(1)+e(1)' | bc -l  # sin(1)+cos(1)+atan(1)+ln(1)+exp(1)
echo 'scale=100;4*a(1)' | bc -l   # Pi, 3.1415..., with 100 decimal digit precision
echo 'scale=5000;4*a(1)' | bc -l  # Pi, 3.1415..., with 5000 decimal digit precision within minutes
echo '4!=5' | bc -l               # 1 for True: 4 differs from 5
echo 'if(1!=0)2' | bc -l          # if
echo 'i=1;r=1;while(i<=10){r*=i;i+=1};r' | bc -l  # Factorial of 10; while loop
echo 'r=1;for(i=1;i<=10;i++){r*=i};r' | bc -l     # Factorial of 10; for loop
echo 'define mul(x,y){return x*y}mul(2,3)' | bc   # Functions there
echo '!((1&&0)||1)' | bc          # GNU bc, not POSIX bc: not, and, or (logical operations)
echo 'e(l(2)*1/3)' | bc -l        # 2 ^ 1/3; exponentiation with non-integers
echo 'a[0]=1;a[0]+1' | bc         # Arrays are supported
echo 'obase=2;12' | bc            # Yields 12 converted to binary by setting output base
echo 'obase=2;1/3' | bc -l        # Yields .01010101...: output base affects fractions
echo 'ibase=16;1F' | bc           # Yields 31; sets the input base
echo 'ibase=8;ibase=10;10' | bc   # Yields 8; due to the 1st ibase, the 2nd ibase with 10 is interpreted as 8
echo 'ibase=8;ibase=A;10' | bc    # Yields 10; A is interpreted as 10
echo 'ibase=8;ibase=G;10' | bc    # Yields 16; G is interpreted as 16
result=$( echo '2^200' | bc )     # Stores the result in a variable
bc <<< '2*17'                     # Works in bash
bc -l                             # Starts interactive use; enter quit to quit
bc -l mylib.bc                    # Loads bc code from mylib.bc and starts interactive use

示例會話

[編輯 | 編輯原始碼]

這是一個使用者啟動 bc、進行兩次計算並使用“quit”退出的示例。注意,按下^D(Control-D)也會退出。

$ bc -l
3 + 4
7
2 / 5
.40000000000000000000
quit
$


二進位制數

[編輯 | 編輯原始碼]

從十進位制比率轉換為二進位制[1]

bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
obase=2
3/14
.0011011011011011011011011011011011011011011011011011011011011011010
1/5
.0011001100110011001100110011001100110011001100110011001100110011001

示例指令碼

[編輯 | 編輯原始碼]

某些版本的“bc”將函式和變數名稱限制為一個字母。以下示例具有較長的函式和變數名稱,必須更改才能在這些版本的“bc”上執行。

以下示例已在 OpenBSD bc 上測試,並已透過 Gnu bc 版本 1.06 patchlevel 2 驗證。

此指令碼實現了 辛普森法則 用於積分。函式“integrate”使用“n”個拋物線段逼近從“a”到“b”的定積分。“simpson”的公式取自 維基百科文章。此示例對正弦函式進行積分,但可以透過替換 f 來使用不同的函式。

define f(x) {
  return s(x);
}

define simpson(a,b) {
  return ( (b-a)/6 ) * ( f(a) + 4*f((a+b)/2) + f(b) );
}

define integrate(a,b,n) {
  delta = (b - a) / n;
  result = 0;

  for(i = a; (n = n - 1) + 1; i = i + delta) {
    /*print "calling simpson(", i, ", ", i + delta, ") with n = ", n, "\n";*/
    result = result + simpson(i, i + delta);
  }
  return result;
}

將此放在一個檔案中,例如“simpson”,載入它,並將 f 從 0 積分到 pi(pi 是“4*a(1)”,1 的反正切的 4 倍),使用 100 個間隔

$ bc -l simpson
integrate(0, 4*a(1), 100)
2.00000000067647189101
^D
  • Bc 不支援浮點運算。它支援定點運算,可以透過 scale 將定點小數位數設定為相當大的值。
  • bc 不允許使用科學計數法輸入數字,例如 5.031E10。
  • 在 POSIX 和 GNU bc 中沒有位操作運算子(| 用於或、& 用於和、^ 用於異或、<<、>>)。
  • 在 POSIX bc 中沒有邏輯與和或運算子(&&、||);在 GNU bc 中作為擴充套件提供。
  • 標準庫中的函式數量非常有限。Gavin Howard bc 提供了許多其他函式。

標準庫

[編輯 | 編輯原始碼]

標準庫在使用“-l”選項呼叫 bc 時載入。庫包含大部分作為單個字母提供的三角函式。庫通常在 bc 本身中實現,因此用作 bc 用法的示例。包含的函式有 s(sin)、c(cos)、a(atan)、l(log)、e(exp)和 j(貝塞爾函式)。

連結

  • libmath.b in bc-21, opensource.apple.com - 實際上也是 Linux 中使用的 GNU bc
  • bc.library in freebsd-src, github.com
  • bc.library in openbsd/src, github.com
  • lib.bc in gavinhoward/bc, github.com
  • lib2.bc in gavinhoward/bc, github.com - 擴充套件函式

十進位制與二進位制

[編輯 | 編輯原始碼]

如 POSIX 所規定,bc 的行為應如同使用小數點後的十進位制表示而不是通常的二進位制表示進行計算一樣。一個結果是 0.1 可以精確表示,並且 0.1 * 3 正好是 0.3,而在使用二進位制表示的語言中則不然。

[編輯 | 編輯原始碼]
  1. math.stackexchange 問題:查詢給定重複二進位制擴充套件的 fractions
華夏公益教科書