使用 Python 作为计算器
Python 解释器可以直接当作一台强大的计算器使用:支持的数值类型远超普通计算器,运算符丰富,还能通过标准库完成高精度计算、分数运算与进制转换。本节将带你掌握 Python 的算术运算、数值类型、常用数学函数,以及浮点数精度问题的正确处理方式。
前置知识
阅读本节前,建议先了解:第一个 Python 程序,掌握 print() 与交互式模式的基本用法。
基础概念
在 Python 中做运算,需要理解三个层次:数值类型(int、float、complex)、运算符(+ - * / // % **)与内置函数/标准库(abs、round、math、decimal)。Python 的 int 支持任意精度(Arbitrary Precision),不会像 C/Java 那样溢出;float 是双精度浮点数,遵循 IEEE 754 标准,因此存在精度局限。
| 类型 | 英文 | 说明 | 示例 |
|---|---|---|---|
| 整数 | int | 任意精度,无溢出 | 10, -3, 2**100 |
| 浮点数 | float | 双精度,约 15~17 位有效数字 | 3.14, 1e-5 |
| 复数 | complex | 实部 + 虚部 | 3+4j |
| 布尔值 | bool | int 的子类 | True, False |
语法与用法
基础算术运算符一览:
| 运算符 | 名称 | 示例 | 结果 | 说明 |
|---|---|---|---|---|
+ | 加 | 7 + 3 | 10 | 数值相加,字符串拼接 |
- | 减 | 7 - 3 | 4 | 也用于取负 |
* | 乘 | 7 * 3 | 21 | 字符串重复 |
/ | 除 | 7 / 2 | 3.5 | 总是返回 float |
// | 地板除 | 7 // 2 | 3 | 向下取整 |
% | 取模 | 7 % 3 | 1 | 求余数 |
** | 幂 | 2 ** 10 | 1024 | 也可用 pow() |
# 最简可运行示例:基础算术
print(7 + 3) # 10
print(7 / 2) # 3.5 —— 真除法,结果是 float
print(7 // 2) # 3 —— 地板除,向下取整
print(7 % 3) # 1 —— 取余
print(2 ** 10) # 1024 —— 幂运算10
3.5
3
1
1024详细说明
整数:任意精度
Python 的整数没有固定位宽,只要内存允许,可以精确表示任意大的整数:
# 大整数运算:不会有溢出问题
big = 2 ** 100
print(big)
print(big + 1)
print(len(str(big)), "位数")
# 阶乘:100 的阶乘有 158 位
import math
print(math.factorial(20))1267650600228229401496703205376
1267650600228229401496703205377
31 位数
2432902008176640000Python 3.6+ 支持用下划线分隔数字字面量,提升可读性:
# 下划线仅用于可读性,不影响数值
population = 1_400_000_000
salary = 12_000.50
mask = 0b1010_1010 # 二进制
print(population)
print(salary)
print(mask, bin(mask))1400000000
12000.5
170 0b10101010浮点数与精度陷阱
float 遵循 IEEE 754 双精度标准,无法精确表示某些十进制小数,这是所有使用浮点数的语言共有的现象:
# 经典精度问题
print(0.1 + 0.2) # 不等于 0.3
print(0.1 + 0.2 == 0.3) # False
print(f"{0.1 + 0.2:.20f}") # 看看到底是多少0.30000000000000004
False
0.30000000000000004正确的比较方式是使用容差(Tolerance)或改用 decimal:
import math
# 方案一:math.isclose 比较浮点数
a = 0.1 + 0.2
b = 0.3
print(math.isclose(a, b)) # True
print(math.isclose(a, b, rel_tol=1e-9)) # 自定义相对容差
# 方案二:用 decimal 做精确十进制运算
from decimal import Decimal
print(Decimal("0.1") + Decimal("0.2")) # 精确得到 0.3
print(Decimal("0.1") + Decimal("0.2") == Decimal("0.3")) # TrueTrue
True
0.3
True金额计算绝不能用 float
0.1 + 0.2 != 0.3 在金融场景会造成真实损失。涉及金额的计算必须使用 decimal.Decimal(构造时传入字符串),或直接以「分」为单位的整数运算。
# 推荐:金额用 Decimal 并以字符串构造
from decimal import Decimal, ROUND_HALF_UP
unit_price = Decimal("19.99")
quantity = 3
total = unit_price * quantity
# 按财务惯例四舍五入到分
final = total.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
print(f"单价 {unit_price} × {quantity} = {final}")
# 不推荐:用 float 计算金额
bad = 19.99 * 3
print(f"float 计算:{bad}")单价 19.99 × 3 = 59.97
float 计算:59.970000000000006除法与取整的细节
Python 的地板除 // 向负无穷方向取整,这与 C 语言的「向零取整」不同:
# 正数
print(7 // 2) # 3
print(7 % 2) # 1
# 负数:地板除向下取整
print(-7 // 2) # -4(不是 -3)
print(-7 % 2) # 1
# 恒等式:a == (a // b) * b + (a % b) 总是成立
a, b = -7, 2
print(a == (a // b) * b + (a % b))3
1
-4
1
True| 取整方式 | 写法 | -7 与 2 的结果 |
|---|---|---|
| 向下取整(地板) | -7 // 2 | -4 |
| 向零取整(截断) | int(-7 / 2) | -3 |
| 四舍五入 | round(-3.5) | -4 |
| 向上取整 | math.ceil(-3.5) | -3 |
import math
value = -3.5
print(f"round: {round(value)}")
print(f"floor: {math.floor(value)}")
print(f"ceil: {math.ceil(value)}")
print(f"trunc: {math.trunc(value)}")
print(f"int(): {int(value)}")round: -4
floor: -4
ceil: -3
trunc: -3
int(): -3内置数学函数与 math 模块
无需导入即可使用的内置函数:
| 函数 | 说明 | 示例 | 结果 |
|---|---|---|---|
abs(x) | 绝对值 | abs(-5) | 5 |
round(x, n) | 四舍五入到 n 位 | round(3.14159, 2) | 3.14 |
pow(x, y) | 幂运算 | pow(2, 8) | 256 |
divmod(a, b) | 同时返回商与余 | divmod(7, 2) | (3, 1) |
min() / max() | 最小/最大值 | max(1, 5, 3) | 5 |
sum() | 求和 | sum([1, 2, 3]) | 6 |
# 内置函数演示
print(abs(-5))
print(round(3.14159, 2))
print(pow(2, 8))
print(divmod(7, 2))
print(min([4, 2, 9]), max([4, 2, 9]))
print(sum([1, 2, 3, 4]))5
3.14
256
(3, 1)
2 9
10math 模块提供常见数学函数与常量:
import math
print(f"圆周率 π = {math.pi:.10f}")
print(f"自然常数 e = {math.e:.10f}")
print(f"√2 = {math.sqrt(2):.10f}")
print(f"log10(1000) = {math.log10(1000)}")
print(f"sin(π/6) = {math.sin(math.pi / 6)}")
print(f"5! = {math.factorial(5)}")
print(f"gcd(24, 36) = {math.gcd(24, 36)}")
print(f"组合数 C(5,2) = {math.comb(5, 2)}")
print(f"向上取整 ceil(2.1) = {math.ceil(2.1)}")圆周率 π = 3.1415926536
自然常数 e = 2.7182818285
√2 = 1.4142135624
log10(1000) = 3.0
sin(π/6) = 0.49999999999999994
5! = 120
gcd(24, 36) = 12
组合数 C(5,2) = 10
向上取整 ceil(2.1) = 3进制转换与位运算
Python 支持二进制、八进制、十六进制字面量,以及相互转换:
# 字面量写法
binary = 0b1010 # 二进制 10
octal = 0o17 # 八进制 15
hexadecimal = 0xFF # 十六进制 255
decimal = 255
# 转换函数
print(bin(decimal)) # 转二进制字符串
print(oct(decimal)) # 转八进制字符串
print(hex(decimal)) # 转十六进制字符串
print(int("11111111", 2)) # 从二进制字符串解析
print(int("ff", 16)) # 从十六进制字符串解析0b11111111
0o377
0xff
255
255位运算符适合处理标志位与底层数据:
# 权限位示例:读 4、写 2、执行 1
READ, WRITE, EXECUTE = 0b100, 0b010, 0b001
permission = READ | WRITE # 组合权限
print(f"权限值:{permission},二进制:{permission:b}")
# 检查是否具备某权限
print(f"有读权限:{bool(permission & READ)}")
print(f"有执行权限:{bool(permission & EXECUTE)}")
# 移除权限
permission &= ~WRITE
print(f"移除写权限后:{permission:b}")
# 异或用于切换标志位
print(f"切换执行位:{permission ^ EXECUTE:b}")权限值:6,二进制:110
有读权限:True
有执行权限:False
移除写权限后:100
切换执行位:101实战示例
示例一:复利计算器
复利是金融中最常见的计算场景,涉及幂运算与精度处理:
from decimal import Decimal, ROUND_HALF_UP
def compound_interest(
principal: Decimal,
annual_rate: Decimal,
years: int,
periods_per_year: int = 12,
) -> Decimal:
"""
计算复利终值。
公式:A = P * (1 + r/n) ** (n*t)
principal: 本金
annual_rate: 年利率(如 0.045 表示 4.5%)
years: 年数
periods_per_year: 每年计息次数(默认按月)
"""
n = Decimal(periods_per_year)
rate_per_period = annual_rate / n
total_periods = n * Decimal(years)
amount = principal * (1 + rate_per_period) ** int(total_periods)
# 保留到分
return amount.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
principal = Decimal("100000")
rate = Decimal("0.045")
print(f"{'年数':>4}{'终值(元)':>16}{'收益(元)':>16}")
for years in (1, 3, 5, 10, 20):
amount = compound_interest(principal, rate, years)
profit = amount - principal
print(f"{years:>4}{amount:>16,.2f}{profit:>16,.2f}") 年数 终值(元) 收益(元)
1 104,593.79 4,593.79
3 115,037.15 15,037.15
5 126,481.02 26,481.02
10 159,974.62 59,974.62
20 255,918.79 155,918.79示例二:科学计算与单位换算
利用 math 模块解决实际工程计算:
import math
def calc_triangle_area(a: float, b: float, c: float) -> float:
"""海伦公式:根据三边求三角形面积"""
# 三角不等式校验
if a + b <= c or a + c <= b or b + c <= a:
raise ValueError("三边无法构成三角形")
s = (a + b + c) / 2 # 半周长
return math.sqrt(s * (s - a) * (s - b) * (s - c))
def celsius_to_fahrenheit(celsius: float) -> float:
"""摄氏度转华氏度"""
return celsius * 9 / 5 + 32
def kmh_to_ms(speed_kmh: float) -> float:
"""千米每小时转米每秒"""
return speed_kmh * 1000 / 3600
# 计算三角形面积
print(f"三角形面积:{calc_triangle_area(3, 4, 5):.2f}")
# 温度换算
for c in (0, 37, 100):
print(f"{c:>4}°C = {celsius_to_fahrenheit(c):>6.1f}°F")
# 速度换算
print(f"120 km/h = {kmh_to_ms(120):.2f} m/s")三角形面积:6.00
0°C = 32.0°F
37°C = 98.6°F
100°C = 212.0°F
120 km/h = 33.33 m/s示例三:统计分析
结合内置函数与 statistics 模块,完成一组数据的统计分析:
import statistics
# 一周的销售额
sales = [12800, 15300, 11200, 17800, 16400, 22500, 19800]
print(f"总销售额:{sum(sales):,} 元")
print(f"平均:{statistics.mean(sales):,.2f} 元")
print(f"中位数:{statistics.median(sales):,} 元")
print(f"标准差:{statistics.stdev(sales):,.2f}")
print(f"最高:{max(sales):,} 元(第 {sales.index(max(sales)) + 1} 天)")
print(f"最低:{min(sales):,} 元(第 {sales.index(min(sales)) + 1} 天)")
print(f"极差:{max(sales) - min(sales):,} 元")
# 环比增长
growth = [
(sales[i] - sales[i - 1]) / sales[i - 1]
for i in range(1, len(sales))
]
print(f"平均环比增长:{statistics.mean(growth):.2%}")总销售额:115,800 元
平均:16,542.86 元
中位数:16,400 元
标准差:3,940.22
最高:22,500 元(第 6 天)
最低:11,200 元(第 1 天)
极差:11,300 元
平均环比增长:9.01%statistics vs math
statistics 面向统计场景(均值、中位数、方差),返回类型可能为 Fraction 或 float;math 面向数学函数(三角、对数、幂)。做数据分析统计优先用 statistics。
注意事项
/总是返回 float:即使4 / 2也得到2.0,需要整数用//。- 浮点数不能直接用
==比较:用math.isclose()或Decimal。 - 金额计算禁用 float:用
Decimal(以字符串构造)或整数分单位。 - 负数地板除向负无穷取整:
-7 // 2 == -4,不是-3。 round()使用银行家舍入:round(2.5)得2而非3,round(0.5)得0。需要四舍五入请用Decimal的ROUND_HALF_UP。- 整数除法与取模满足恒等式:
a == (a // b) * b + a % b,调试时可用来验证。 - 大整数运算有性能代价:超大整数的乘除较慢,必要时改用 NumPy 或
decimal。
# 银行家舍入演示
print(round(0.5), round(1.5), round(2.5), round(3.5)) # 0 2 2 4
# 需要传统四舍五入时,用 Decimal
from decimal import Decimal, ROUND_HALF_UP
print(Decimal("2.5").quantize(Decimal("1"), rounding=ROUND_HALF_UP)) # 30 2 2 4
3最佳实践
- 数值类型选择:计数用
int,测量用float,金额用Decimal,科学计算用numpy。 - 用
Decimal处理一切财务数据:从构造到运算全程使用,不要中途混入 float。 - 为常量命名:把
3.14159这样的字面量提取为PI = Decimal("3.14159")。 - 显式处理除零:除法前判断分母,或用
try/except ZeroDivisionError。 - 用
divmod同时取商余:比分别计算//与%更高效。 - 需要高精度科学计算时用
numpy:NumPy 的浮点运算经过向量化优化,比纯 Python 快得多。 - 对外输出统一格式化:用 f-string 的格式说明符保证一致的小数位与千分位。
# 推荐:安全的除法封装
from decimal import Decimal, DivisionByZero, ROUND_HALF_UP
def safe_divide(a: Decimal, b: Decimal, digits: int = 4) -> Decimal:
"""安全除法,除数为零时返回 Decimal('0') 并给出提示"""
if b == 0:
print("警告:除数为零,返回 0")
return Decimal("0")
result = a / b
return result.quantize(Decimal("0." + "0" * (digits - 1) + "1"), rounding=ROUND_HALF_UP)
print(safe_divide(Decimal("10"), Decimal("3")))
print(safe_divide(Decimal("10"), Decimal("0")))3.3333
警告:除数为零,返回 0
0下一节
继续学习:字符串基本操作