bc(Basic Calculator)是Linux系统中一个功能强大的数学计算语言解释器。它支持交互式执行数学语句,也支持从标准输入或文件读取计算指令。bc可以进行高精度计算,支持变量、函数、条件语句、循环等编程特性,是Shell脚本中进行复杂数学运算的理想工具。
bc包。它支持任意精度数字,这在金融计算和科学计算中特别有用。
bc [选项] [文件...]
| 选项 | 说明 |
|---|---|
-h, --help |
显示帮助信息 |
-i, --interactive |
强制交互模式 |
-l, --mathlib |
使用预定义的数学库 |
-w, --warn |
显示POSIX bc的扩展警告 |
-s, --standard |
严格遵循POSIX bc语言 |
-q, --quiet |
不显示欢迎横幅 |
-v, --version |
显示版本信息 |
-e, --expression=EXPR |
执行表达式(某些版本支持) |
-f, --file=FILE |
执行文件中的bc代码(某些版本支持) |
大多数Linux发行版默认安装了bc命令。如果没有安装,可以使用以下命令:
sudo apt update
sudo apt install bc
sudo yum install bc
# 或使用dnf(Fedora/RHEL8+)
sudo dnf install bc
sudo pacman -S bc
bc支持基本的数学运算符:
| 运算符 | 说明 | 示例 | 结果 |
|---|---|---|---|
+ |
加法 | echo "5 + 3" | bc |
8 |
- |
减法 | echo "10 - 4" | bc |
6 |
* |
乘法 | echo "6 * 7" | bc |
42 |
/ |
除法 | echo "10 / 3" | bc |
3 |
% |
取模 | echo "10 % 3" | bc |
1 |
^ |
幂运算 | echo "2 ^ 8" | bc |
256 |
sqrt() |
平方根(需要-l选项) | echo "sqrt(16)" | bc -l |
4 |
进行简单的数学计算:
# 简单计算
echo "5 + 3" | bc
# 复杂表达式
echo "(2 + 3) * 4 - 5" | bc
# 浮点计算(需要设置scale)
echo "scale=2; 10 / 3" | bc
# 幂运算
echo "2 ^ 10" | bc
进入bc交互式计算环境:
# 进入交互模式
bc
# 在交互模式中可以输入:
# 5 + 3
# 10 / 3
# scale=5
# 10 / 3
# quit # 退出
使用-l选项加载数学库,支持更多数学函数:
# 计算平方根
echo "sqrt(25)" | bc -l
# 计算正弦值(弧度)
echo "s(3.14159)" | bc -l
# 计算余弦值
echo "c(3.14159)" | bc -l
# 计算自然对数
echo "l(10)" | bc -l
# 计算指数
echo "e(1)" | bc -l
# 计算arctangent
echo "a(1)" | bc -l
bc支持不同进制之间的转换:
# 十进制转二进制
echo "obase=2; 255" | bc
# 十进制转十六进制
echo "obase=16; 255" | bc
# 二进制转十进制
echo "ibase=2; 11111111" | bc
# 十六进制转十进制
echo "ibase=16; FF" | bc
# 复杂转换:二进制转十六进制
echo "ibase=2; obase=16; 11111111" | bc
在Shell脚本中使用bc进行复杂计算:
#!/bin/bash
# 计算圆的面积
PI=3.14159
radius=5
# 方法1:使用变量
area=$(echo "$PI * $radius * $radius" | bc)
echo "圆的面积(半径=$radius): $area"
# 方法2:使用scale控制精度
area=$(echo "scale=2; $PI * $radius ^ 2" | bc)
echo "圆的面积(保留两位小数): $area"
# 计算复利
principal=1000
rate=0.05
years=10
amount=$(echo "scale=2; $principal * (1 + $rate) ^ $years" | bc)
echo "复利计算(本金=$principal, 利率=$rate, 年数=$years): $amount"
在bc中定义和使用函数:
# 定义计算阶乘的函数
cat > factorial.bc << 'EOF'
define factorial(n) {
if (n <= 1) return 1;
return n * factorial(n-1);
}
# 使用函数
factorial(5)
factorial(10)
EOF
# 执行bc脚本
bc factorial.bc
使用bc的编程特性:
# 计算斐波那契数列
cat > fibonacci.bc << 'EOF'
define fibonacci(n) {
if (n <= 0) return 0;
if (n == 1) return 1;
return fibonacci(n-1) + fibonacci(n-2);
}
# 打印前10个斐波那契数
for (i = 1; i <= 10; i++) {
print "fibonacci(", i, ") = ", fibonacci(i), "\n";
}
EOF
bc fibonacci.bc
使用scale控制计算精度:
# 设置精度为10位小数
echo "scale=10; 22 / 7" | bc
# 不同精度下的计算结果
for scale in 0 2 5 10 20; do
result=$(echo "scale=$scale; 22 / 7" | bc)
echo "精度 $scale: $result"
done
# 计算π的近似值
echo "scale=20; 4*a(1)" | bc -l
使用bc进行金融计算:
#!/bin/bash
# 贷款计算器
principal=100000 # 本金
annual_rate=0.05 # 年利率
years=20 # 贷款年限
# 月利率
monthly_rate=$(echo "scale=10; $annual_rate / 12" | bc)
# 总期数(月)
n=$(echo "$years * 12" | bc)
# 等额本息月供计算公式: M = P * r * (1+r)^n / ((1+r)^n - 1)
M=$(echo "scale=2; $principal * $monthly_rate * (1 + $monthly_rate) ^ $n / ((1 + $monthly_rate) ^ $n - 1)" | bc)
echo "月供: ¥$M"
# 总还款额
total=$(echo "scale=2; $M * $n" | bc)
echo "总还款额: ¥$total"
# 总利息
interest=$(echo "scale=2; $total - $principal" | bc)
echo "总利息: ¥$interest"
进行科学计算:
#!/bin/bash
# 科学计算示例
# 计算自然常数e
echo "计算自然常数e:"
echo "scale=15; e(1)" | bc -l
# 计算圆周率π
echo -e "\n计算圆周率π:"
echo "scale=15; 4*a(1)" | bc -l
# 计算黄金分割率
echo -e "\n计算黄金分割率:"
echo "scale=15; (1+sqrt(5))/2" | bc -l
# 计算欧拉恒等式 e^(iπ) + 1 = 0
# 注意:bc不支持复数计算,这里只计算实数部分
echo -e "\n计算e^(iπ)的实数部分:"
echo "scale=15; c(3.141592653589793)" | bc -l
使用bc进行统计分析:
#!/bin/bash
# 统计计算示例
# 数据点
data="10 15 20 25 30 35 40"
# 计算平均值
sum=0
count=0
for num in $data; do
sum=$(echo "$sum + $num" | bc)
count=$((count + 1))
done
average=$(echo "scale=2; $sum / $count" | bc)
echo "平均值: $average"
# 计算方差
sum_squared_diff=0
for num in $data; do
diff=$(echo "$num - $average" | bc)
squared_diff=$(echo "$diff * $diff" | bc)
sum_squared_diff=$(echo "$sum_squared_diff + $squared_diff" | bc)
done
variance=$(echo "scale=2; $sum_squared_diff / $count" | bc)
echo "方差: $variance"
std_dev=$(echo "scale=2; sqrt($variance)" | bc -l)
echo "标准差: $std_dev"
创建单位转换函数:
cat > conversions.bc << 'EOF'
/* 单位转换函数库 */
/* 温度转换 */
define celsius_to_fahrenheit(c) {
return c * 9 / 5 + 32
}
define fahrenheit_to_celsius(f) {
return (f - 32) * 5 / 9
}
/* 长度转换 */
define meters_to_feet(m) {
return m * 3.28084
}
define feet_to_meters(ft) {
return ft / 3.28084
}
/* 重量转换 */
define kilograms_to_pounds(kg) {
return kg * 2.20462
}
define pounds_to_kilograms(lb) {
return lb / 2.20462
}
/* 示例使用 */
print "20°C = ", celsius_to_fahrenheit(20), "°F\n"
print "68°F = ", fahrenheit_to_celsius(68), "°C\n"
print "2 meters = ", meters_to_feet(2), " feet\n"
print "5 kg = ", kilograms_to_pounds(5), " pounds\n"
EOF
bc conversions.bc
| 函数/变量 | 说明 | 示例 |
|---|---|---|
scale |
设置小数精度 | scale=5 |
ibase |
设置输入数字的进制(2-16) | ibase=16 |
obase |
设置输出数字的进制(2-16) | obase=2 |
last |
上一个计算结果的值 | last * 2 |
length() |
返回数字的位数 | length(12345) |
read() |
从标准输入读取数字 | x = read() |
sqrt() |
平方根(需要-l选项) | sqrt(16) |
s() |
正弦函数(弧度) | s(3.14159) |
c() |
余弦函数(弧度) | c(3.14159) |
a() |
反正切函数 | a(1) |
l() |
自然对数 | l(10) |
e() |
指数函数 | e(1) |
j() |
贝塞尔函数(某些版本) | j(1, 1) |
| 工具 | 优点 | 缺点 |
|---|---|---|
| bc | 高精度计算,支持编程特性,函数,进制转换 | 需要管道或文件输入,语法相对复杂 |
| expr | 简单,直接,Shell内置或轻量级 | 只能整数运算,功能有限 |
| awk | 文本处理能力强,支持浮点运算 | 语法复杂,不适合纯数学计算 |
| $(( )) | Shell内置,速度快,简单表达式 | 只能整数运算,功能有限 |
| python/perl | 功能强大,库丰富 | 需要解释器,启动慢,依赖多 |
使用scale变量控制小数精度:
# 显示2位小数
echo "scale=2; 10 / 3" | bc
# 显示10位小数
echo "scale=10; 22 / 7" | bc
# 在交互模式中设置
bc
scale=20
22/7
quit
注意:scale只影响除法、平方根等运算,不影响乘法等。
标准的bc不支持复数计算。但可以通过一些技巧模拟:
octave、python、R等# 简单复数运算模拟
# 计算 (3+4i) * (2+5i)
# 实部: 3*2 - 4*5 = 6 - 20 = -14
# 虚部: 3*5 + 4*2 = 15 + 8 = 23
# 结果: -14 + 23i
real=$(echo "3*2 - 4*5" | bc)
imag=$(echo "3*5 + 4*2" | bc)
echo "结果: $real + ${imag}i"
bc默认会截断小数,而不是四舍五入。要实现四舍五入,可以使用以下技巧:
# 四舍五入到整数
echo "scale=0; (10/3 + 0.5)/1" | bc
# 四舍五入到2位小数
echo "scale=2; x=10/3; (x*100 + 0.5)/100" | bc
# 通用四舍五入函数
cat > round.bc << 'EOF'
define round(x, n) {
auto scale, factor
scale = n
factor = 10 ^ scale
return ((x * factor) + 0.5) / factor
}
round(10/3, 2)
round(10/3, 0)
EOF
bc round.bc
可以。bc支持任意精度计算,可以处理非常大的数字:
# 计算大数的阶乘
echo "define f(n) { if (n <= 1) return 1; return n * f(n-1); } f(100)" | bc
# 计算大数的幂
echo "2 ^ 1000" | bc | head -5 # 只显示前5行
# 计算斐波那契大数
cat > big_fib.bc << 'EOF'
define fib(n) {
if (n <= 0) return 0;
if (n == 1) return 1;
a = 0;
b = 1;
for (i = 2; i <= n; i++) {
c = a + b;
a = b;
b = c;
}
return b;
}
fib(100)
EOF
bc big_fib.bc
注意:非常大的计算可能会消耗大量内存和时间。
bc -l加载数学库,获得更多数学函数$(echo "表达式" | bc)获取计算结果scale变量控制浮点数精度ibase和obase进行进制转换bc file.bc调用last变量引用上一次计算结果Ctrl+D退出-q选项隐藏欢迎横幅,适合脚本使用逆波兰式计算器,bc的底层工具
表达式计算工具,主要用于整数运算
文本处理和计算工具
通用编程语言,强大的科学计算能力