python round四舍五入和decimal库精确四舍五入

文章目录

Pythondecimal 库提供了高精度的十进制浮点数运算功能,特别适用于需要精确小数运算的场景,如金融计算。以下是 decimal 库和 Decimal 类中 quantize 方法的详解:

decimal 库概述

decimal 模块以三个核心概念为中心:十进制数(Decimal)、算术上下文(Context)和信号(Signals)。十进制数是不可变的,包含符号、系数数字和一个指数。算术上下文定义了精度、舍入规则等。信号用于处理计算中的异常条件。

Decimal 类

Decimal 类是 decimal 模块中用于表示十进制数的类。它支持从字符串、整数或浮点数创建 Decimal 对象,并进行精确的算术运算。

quantize 方法

quantize 方法用于将 Decimal 对象舍入到指定的精度。该方法接受一个 Decimal 对象作为参数,并根据该对象的值对原 Decimal 对象进行舍入。舍入后的值将具有与参数相同的指数(即小数点后的有效数字位数)。

用法
python 复制代码
from decimal import Decimal

# 创建 Decimal 对象
d = Decimal('123.456')

# 将 Decimal 对象舍入到小数点后两位
quantized_d = d.quantize(Decimal('0.01'))
print(quantized_d)  # 输出: 123.46
参数
  • quantizer:一个 Decimal 对象,指定了舍入的精度。
  • rounding:可选参数,指定舍入模式,默认为 ROUND_HALF_UP(四舍五入)。其他模式包括 ROUND_DOWNROUND_UP 等。
舍入模式
  • ROUND_HALF_UP:四舍五入,当要舍入的数字正好在两个可舍入的数字中间时,向上舍入到最近的较大值。
  • ROUND_DOWN:总是向下舍入。
  • ROUND_UP:总是向上舍入。
  • ROUND_HALF_DOWN:如果最后一个有效数字大于或等于 5,则向上舍入;否则向下舍入。
  • ROUND_HALF_EVEN:类似于 ROUND_HALF_DOWN,但如果最后一个有效数字为 5,则会检查前一位,偶数值会导致结果向下舍入,奇数值导致结果向上舍入。
其他常用方法
  • adjusted():返回调整后的指数,直到只剩下前导数字。
  • compare(other):比较两个 Decimal 实例的值。
  • copy_abs():返回参数的绝对值。
  • is_normal(context=None):如果参数是一个有限正规数,返回 True
  • is_zero():如果参数是 0,则返回 True
  • ln(context=None):返回操作数的自然对数(以 e 为底)。
  • log10(context=None):返回操作数的自然对数(以 10 为底)。
  • max(other, context=None):比较两个数值大小,并返回大的值。
  • min(other, context=None):比较两个数值大小,并返回小的值。

decimal 模块和 Decimal 类提供了强大的工具来处理需要高精度计算的场景,确保计算结果的准确性和可靠性。

举例

ROUND_HALF_UPROUND_HALF_DOWN 是两种不同的舍入模式,它们在处理数字中间值时的舍入行为有所不同。以下是这两种舍入模式的具体解释和示例:

ROUND_HALF_UP(四舍五入)

ROUND_HALF_UP 是最常用的舍入模式,当要舍入的数字正好在两个可舍入的数字中间时,它将向上舍入到最近的较大值。换句话说,如果舍入位后的数字是5或更大,就会向上舍入;如果小于5,则向下舍入。

示例

  • round(2.5) 会得到 3,因为 .5 正好在 23 之间,按照 ROUND_HALF_UP 规则,向上舍入到 3
  • round(3.5) 也会得到 4,同理,.5 使得 3 向上舍入到 4
ROUND_HALF_DOWN(五舍六入)

ROUND_HALF_DOWN 是一种较少使用的舍入模式,它在处理数字中间值时,如果舍入位后的数字是5,则向下舍入到最近的较小值。

示例

  • round(2.5) 会得到 2,因为 .5 使得 2 向下舍入到 2
  • round(3.5) 会得到 3,因为 .5 使得 3 向下舍入到 3

Pythondecimal 模块中,可以通过设置 quantize 方法的 rounding 参数来指定舍入模式。以下是如何使用这两种舍入模式的示例:

python 复制代码
from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_DOWN

# 创建 Decimal 对象
d = Decimal('123.5')

# 使用 ROUND_HALF_UP 模式舍入
rounded_up = d.quantize(Decimal('1'), rounding=ROUND_HALF_UP)
print(rounded_up)  # 输出: 124

# 使用 ROUND_HALF_DOWN 模式舍入
rounded_down = d.quantize(Decimal('1'), rounding=ROUND_HALF_DOWN)
print(rounded_down)  # 输出: 123

在这个示例中,123.5 使用 ROUND_HALF_UP 模式舍入后得到 124,而使用 ROUND_HALF_DOWN 模式舍入后得到 123。这展示了两种模式在处理 .5 这样的中间值时的不同行为。

round

Python 内置的 round 函数和 decimal 模块中的 Decimal 类的 quantize 方法都可以用来进行数值的四舍五入,但它们在默认行为上有所不同,并且 decimal 模块提供了更多的灵活性和精确控制。

Python 内置 round 函数
  • Python 3 中的 round 函数遵循"银行家舍入法"(也称为"偶数舍入法"),即当要舍入的数字正好在两个可舍入的数字中间时(例如 2.5-2.5),它会舍入到最近的偶数。这意味着 round(2.5) 会得到 2,而 round(3.5) 会得到 4
  • round 函数的行为可以通过指定第二个参数 ndigits 来控制舍入的位数,但舍入模式默认是 ROUND_HALF_TO_EVEN(即"银行家舍入法")。
decimal 模块中的 Decimal 类和 quantize 方法
  • decimal.Decimal 类的 quantize 方法默认遵循 ROUND_HALF_UP 舍入模式,即当要舍入的数字正好在两个可舍入的数字中间时,它会向上舍入到最近的较大值。这意味着 quantize(Decimal('2.5'), Decimal('1')) 会得到 Decimal('3')
  • quantize 方法允许你指定舍入模式,例如 ROUND_HALF_DOWNROUND_HALF_EVEN(与 Python 内置 round 函数的默认行为相同)等。
对应关系

如果你想要使 Python 内置的 round 函数的行为与 decimal 模块中的某个舍入模式相对应,可以这样对应:

  • Python 内置 round 函数的默认行为(ROUND_HALF_TO_EVEN)对应于 decimal 模块中的 ROUND_HALF_EVEN
  • 如果你想要 Python 的 round 函数行为与 decimal 模块中的 ROUND_HALF_UP 相对应,你需要手动实现这种舍入逻辑,因为 round 函数本身不提供直接的方式来改变其舍入模式。

以下是如何使用 decimal 模块来模拟 Python 内置 round 函数的默认行为的示例:

python 复制代码
from decimal import Decimal, ROUND_HALF_EVEN

# 创建 Decimal 对象
d = Decimal('2.5')

# 使用 ROUND_HALF_EVEN 模式舍入
rounded_value = d.quantize(Decimal('1'), rounding=ROUND_HALF_EVEN)
print(rounded_value)  # 输出: 2

在这个示例中,quantize 方法使用了 ROUND_HALF_EVEN 舍入模式,这与 Python 内置 round 函数的默认行为相匹配。

真正的四舍五入

Python中,内置的round函数实际上执行的是"银行家舍入法"(ROUND_HALF_TO_EVEN),这意味着当数字正好位于两个整数的中间时,它会舍入到最近的偶数。例如,round(2.5)会得到2,而round(3.5)会得到4

如果你想要实现真正的四舍五入,即当数字正好位于两个整数中间时向上舍入,你可以自定义一个函数来实现这个逻辑。以下是一个简单的实现:

python 复制代码
def true_round(number):
    if number - int(number) < 0.5:
        return int(number)
    else:
        return int(number) + 1

# 测试真正的四舍五入
print(true_round(2.5))  # 输出: 3
print(true_round(3.5))  # 输出: 4
print(true_round(4.5))  # 输出: 5

这个true_round函数检查数字的小数部分是否小于0.5。如果是,它就向下舍入;否则,它向上舍入。

如果你想要处理负数,可以稍微修改这个函数:

python 复制代码
def true_round(number):
    if number < 0:
        return int(number) - (1 if number % 1 else 0)
    else:
        return int(number) + (1 if number % 1 else 0)

# 测试真正的四舍五入,包括负数
print(true_round(2.5))  # 输出: 3
print(true_round(3.5))  # 输出: 4
print(true_round(-2.5)) # 输出: -3
print(true_round(-3.5)) # 输出: -4

在这个版本中,我们检查数字的符号,并相应地调整舍入逻辑。对于正数,如果小数部分大于0,则向上舍入;对于负数,如果小数部分大于0(即数字更接近于更小的整数),则向下舍入(实际上是向更负的方向舍入)。

相关推荐
sunshine6413 分钟前
【CSS】实现tag选中对钩样式
前端·css·css3
Q_19284999067 分钟前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
PyAIGCMaster9 分钟前
ubuntu装P104驱动
linux·运维·ubuntu
奈何不吃鱼9 分钟前
【Linux】ubuntu依赖安装的各种问题汇总
linux·运维·服务器
icy、泡芙11 分钟前
T527-----音频调试
linux·驱动开发·音视频
sdaxue.com13 分钟前
帝国CMS:如何去掉帝国CMS登录界面的认证码登录
数据库·github·网站·帝国cms·认证码
aherhuo14 分钟前
kubevirt网络
linux·云原生·容器·kubernetes
zzzhpzhpzzz23 分钟前
Ubuntu如何查看硬件型号
linux·运维·ubuntu
张国荣家的弟弟24 分钟前
【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?
java·jar·bi
蜜獾云25 分钟前
linux firewalld 命令详解
linux·运维·服务器·网络·windows·网络安全·firewalld