px普贤教程PuXian
普贤教程 › 生态包

精确计算与统计

浮点算钱会出 0.30000000000000004 这类答案。这一组包解决三件事:精确小数(decimal / money)、任意精度整数(big / fractions)、单位与统计(units / stats / percent)。

精确小数

px
import decimal

print(dec_add("0.1", "0.2").ok())     # Ok(0.3)    ← 不是 0.30000000000000004
print(dec_mul("1.10", "3").ok())      # Ok(3.30)   ← 保留尾随零(金额要)
print(dec_cmp("1.20", "1.2"))         # 0          ← 数值相等
金额绝不用 float0.1 + 0.2 == 0.3 在 float 下是 false。金额可以用「整数分」存(推荐),或 decimal 字符串运算;不要在中间用 float() 转一遍,转了就等于没用。

金额格式化

px
import money

print(mn_format(1234.5).ok())          # Ok(¥1,234.50)
print(mn_parse("1,234.50").ok())       # Ok(1234.5)
print(mn_add("10.00", "0.05"))         # 精确相加
print(mn_compare("10.00", "9.99"))     # 1

货币符号与小数位由币种决定(mn_symbol / mn_decimals),JPY 两位变零位这类差异它替你想好了。

大整数与分数

px
import big

print(big_add("99999999999999999999", "1").ok())
# 100000000000000000000
print(big_mul("12345678901234567890", "98765432109876543210").ok())
# 1219326311370217952237463801111263526900

import fractions
# 有理数以分数串表示("1/3"),运算保持精确,不经过 float
整数字面量超过 64 位会静默回绕2 ** 64 得到 0(不是报错,是回绕)。要大数就用字符串进 big_*,别先写成整数字面量。

单位换算

px
import units

print(un_convert(1.0, "GB", "MB").ok())    # 1024.0
print(un_convert(100, "c", "f").ok())      # 212.0   ← 温度专用路径
print(un_convert(100, "km", "m").ok())     # 100000.0

温度不能和长度互转(会返回 Err),这是它比「一律乘系数」聪明的地方。

描述统计

px
import stats

print(stats_mean([1, 2, 3, 4]))            # 2.5
print(stats_median([1, 2, 3, 4, 5]))       # 3
print(stats_percentile([1, 2, 3, 4, 5], 50))  # 3.0
print(stats_quartiles([1, 2, 3, 4, 5]))    # 四分位

# 线性回归在 statx 包里(st_linreg / st_pearson)
import statx
print(st_linreg([1, 2, 3], [2, 4, 6]).ok())   # [2.0, 0.0, 1.0]

百分号格式化(URL 编码,不是百分比)

px
import percent
print(percent_encode("你好 world"))       # %E4%BD%A0%E5%A5%BD%20world
print(percent_decode("%E4%BD%A0"))        # 你
别被包名骗了percent 是 URL 百分号编码(RFC 3986),不是「百分比计算」。算百分比就是 a * 100 / b,不需要包。

复利/精度这类计算的建议

  • 钱:整数分存储 + decimal 或 money 运算,展示时格式化。
  • 比率:用 fractions 保留精确值,最后一步才转小数。
  • 大整数 ID:字符串进出,别转 int。
  • 浮点只用于「测量值」:耗时、温度、坐标。用于「金额」「分数」必错。