跳转到内容

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
华夏公益教科书