decimal 是 Python 提供的十进制浮点运算模块,可用于避免二进制浮点(如 float)带来的精度误差。
常见应用场景:
(1)金融与会计计算,货币金额对精度要求极高。
(2)精密科学计算,如天文、物理实验等。
(3)精度可控的用户输入和显示。
◆ ◆ ◆
核心概念
1、Decimal 类型
与内建的 float 类型不同,Decimal 使用十进制表达并记录每一位有效数字。
from decimal import Decimal
x = Decimal('0.1') + Decimal('0.2')
print(x) # 输出:0.3(精确值)而使用 float:
print(0.1 + 0.2) # 输出:0.30000000000000004(误差)2、上下文控制
decimal 模块允许用户通过“上下文”(Context)设置精度、舍入规则等。
from decimal import getcontext
getcontext().prec = 4 # 设置全局精度为 4 位有效数字◆ ◆ ◆
应用举例
例 1:避免浮点误差(基本用途)
from decimal import Decimal
a = Decimal('1.00')
b = Decimal('0.80')
c = Decimal('0.20')
print(a - b == c) # 输出 True,完全精确例 2:控制精度与舍入方式
from decimal import Decimal, getcontext, ROUND_HALF_UP
getcontext().prec = 6
getcontext().rounding = ROUND_HALF_UP
price = Decimal('2.675')
rounded = price.quantize(Decimal('0.01')) # 四舍五入到两位小数
print("Rounded:", rounded) # 输出:2.68例 3:不推荐的构造方式
from decimal import Decimal
x = Decimal(1.1) # 含精度误差
y = Decimal('1.1') # 推荐写法
print("错误方式:", x)
print("推荐方式:", y)例 4:使用 localcontext() 设置局部精度
from decimal import Decimal, localcontext
x = Decimal('1.23456')
with localcontext() as ctx:
ctx.prec = 3
print("局部精度:", x / Decimal('7')) # 只在 with 块内生效
print("全局精度:", x / Decimal('7')) # 恢复原精度例 5:使用 as_tuple() 获取结构信息
from decimal import Decimal
d = Decimal('123.45')
t = d.as_tuple()
print("符号位:", t.sign) # 0 表示正数
print("数字位:", t.digits) # (1, 2, 3, 4, 5)
print("指数位:", t.exponent) # -2 表示小数点后两位◆ ◆ ◆
常用函数速览
decimal.Context
表示一个计算上下文对象,用于控制精度、舍入方式、异常处理等。
参数:
可通过 decimal.getcontext() 获取当前上下文;也可新建 Context(prec=28, rounding=...)
返回:Context 对象。常用于 context.add(a, b) 这类方法形式
decimal.Decimal(value)
将字符串、整数、浮点数等转换为高精度的 Decimal 对象。推荐使用字符串作为参数以避免隐式精度误差。
参数:
value:可以是字符串(推荐)、整数或浮点数
返回:Decimal 类型对象
示例:
Decimal('0.1') # 推荐
Decimal(0.1) # 不推荐,存在隐含误差decimal.getcontext()
获取当前线程使用的十进制计算上下文对象,可用于控制精度与舍入方式。
参数:无
返回:当前 Context 对象,可进一步设置属性如 .prec、.rounding 等
decimal.setcontext(context)
设置当前线程的十进制计算上下文。
参数:
context:一个 Context 对象,通常通过 getcontext().copy() 创建副本再修改
返回:无
decimal.localcontext(ctx=None)
创建一个上下文管理器,在 with 语句块中临时替换全局上下文,退出时恢复。
参数:
ctx:可选,指定上下文对象;若为空则使用当前默认上下文的副本
返回:上下文管理器,用于 with 语句
示例:
with decimal.localcontext() as ctx:
ctx.prec = 4
print(Decimal('1.23456') / Decimal('7')) # 局部生效Decimal.quantize(exp, rounding=None)
将当前 Decimal 数值四舍五入到指定的小数精度。
参数:
exp:一个 Decimal,表示目标精度,如 Decimal('0.01') 表示保留两位小数
rounding:舍入方式,如 ROUND_HALF_UP,可选,若不提供则使用上下文默认
返回:处理后新的 Decimal 对象(不会改变原值)
示例:
Decimal('2.675').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) # -> Decimal('2.68')Decimal.copy_abs()
返回当前 Decimal 的绝对值副本。
参数:无
返回:Decimal 类型,去掉符号但保留原数值
Decimal.copy_negate()
返回当前 Decimal 的符号取反副本。
参数:无
返回:Decimal 类型,符号与原值相反
Decimal.as_tuple()
将 Decimal 对象转换为包含符号、数字、指数的三元组。
参数:无
返回:
DecimalTuple(sign, digits, exponent)
例如:Decimal('3.14').as_tuple() → DecimalTuple(sign=0, digits=(3, 1, 4), exponent=-2)
Decimal.to_eng_string()
将 Decimal 对象转换为“工程计数法”字符串形式(指数为 3 的倍数)。
参数:无
返回:字符串,例如 Decimal('1230000').to_eng_string() → '1.23E+6'
◆ ◆ ◆
补充说明
1、若对结果精度要求严格(如货币、计量),必须使用 Decimal 替代 float。
2、使用字符串创建 Decimal,比如,Decimal('0.1'),而不要用 Decimal(0.1)。
3、控制输出精度与舍入行为时,请使用 quantize(),不要依赖格式化字符串。
4、decimal 运算速度略慢于 float,如非高精度任务可用 float。
“点赞有美意,赞赏是鼓励”
热门跟贴