跳转到主要内容

不同舍入模式下的round函数等效

项目描述

圆整器

rounders 包扩展了Python内置的 round 函数的功能。它旨在提供比Python核心和标准库提供的更完整、更一致的十进制舍入功能集。具体来说,它提供

  • 使用除Python默认的银行家舍入模式以外的舍入模式的 round 的替代品。提供了十三种不同的舍入模式。
  • 将数字舍入到指定有效数字的功能,而不是到小数点前后的固定位数。

包内容

通用舍入函数

有四个通用舍入函数。这些函数都接受一个可选的 mode 参数来指定舍入模式,如果没有指定模式,则默认使用 TIES_TO_EVEN(银行家舍入)。

  • round 函数与内置的 round 函数具有相同的签名。它支持按给定的舍入模式向最近的整数舍入,并在保留输入类型的同时舍入到指定的位数。

    >>> from rounders import round, TIES_TO_AWAY, TO_MINUS
    >>> round(2.5)  # The default rounding mode is TIES_TO_EVEN
    2
    >>> round(2.5, mode=TIES_TO_AWAY)  # round halfway cases away from zero
    3
    >>> round(2.97, 1, mode=TO_MINUS)  # round towards negative infinity (like floor)
    2.9
    >>> round(Decimal(-1628), -2, mode=TO_MINUS)  # Decimal and Fraction types supported
    Decimal('-1.7E+3')
    
  • round_to_figures 函数将数字舍入到指定有效数字,而不是到小数点前后指定的位数。

    >>> from rounders import round_to_figures, TO_AWAY
    >>> round_to_figures(1.234567, 3)
    1.23
    >>> round_to_figures(1234567., 3)
    1230000.0
    >>> round_to_figures(0.0001234567, 3)
    0.000123
    >>> round_to_figures(0.0001234567, 3, mode=TO_AWAY)  # round away from zero
    0.000124
    
  • 《round_to_int》和《round_to_places》函数分别提供了《round》函数组合的两个功能:使用给定的舍入模式将《round_to_int》舍入到最近的整数,而《round_to_places》始终期望一个《ndigits》参数,并将其舍入到指定的位数。《round》函数目前是《round_to_int》和《round_to_places》的简单包装。

    >>> from rounders import round_to_int, round_to_places, TO_PLUS
    >>> round_to_int(3.1415, mode=TO_PLUS)
    4
    >>> round_to_places(3.1415, 2, mode=TO_PLUS)
    3.15
    

特定舍入模式的舍入函数

有十三个函数可以作为《round》的替代,但使用特定的舍入模式。例如,如果您总是希望将舍入值舍入到最接近的偶数而不是零,您可以这样操作

>>> from rounders import round_ties_to_away as round
>>> round(4.5)
5
>>> round(1.25, 1)
1.3

或者如果您需要一个接受小数点后数字个数的《math.ceil》版本,您可以这样做

>>> from rounders import ceil
>>> ceil(1.78)
2
>>> ceil(1.782, 2)
1.79
>>> ceil(-1.782, 2)
-1.78

完整的函数列表如下

舍入模式

以下是当前支持的舍入模式及其对应的模式特定舍入函数。

向最近舍入模式

有六个向最近舍入模式:这些都舍入到最接近的目标值(例如,在《round_to_int》的情况下,舍入到最接近的整数),它们仅在处理舍入值方面有所不同。

舍入模式 函数 描述
TIES_TO_EVEN round_ties_to_even 舍入值舍入到最近的偶数值
TIES_TO_ODD round_ties_to_odd 舍入值舍入到最近的奇数值
TIES_TO_AWAY round_ties_to_away 舍入值舍入到零以外的值
TIES_TO_ZERO round_ties_to_zero 舍入值舍入向零
TIES_TO_MINUS round_ties_to_minus 舍入值舍入向负无穷大
TIES_TO_PLUS round_ties_to_plus 舍入值舍入向正无穷大

定向舍入模式

有六个匹配的定向舍入模式:对于这些,任何两个可表示的输出值之间的所有值都将朝同一方向舍入。

舍入模式 函数 描述
TO_EVEN round_to_even 舍入到最近的偶数值
TO_ODD round_to_odd 舍入到最近的奇数值
TO_AWAY round_to_away 舍入到零以外
TO_ZERO round_to_zero 舍入向零
TO_MINUS round_to_minus 舍入向负无穷大
TO_PLUS round_to_plus 舍入向正无穷大

其他舍入模式

有一个其他舍入模式TO_ZERO_05_AWAY,对应的函数是round_to_zero_05_away

舍入模式 函数 描述
TO_ZERO_05_AWAY round_to_zero_05_away 见下文

此舍入模式与TO_ZERO的行为匹配,除了当舍入向零会产生最终的有效数字为05的情况。在这种情况下,它将匹配TO_AWAY的行为。请注意,在这种情况下,如果值已经舍入到所需的位数,则TO_ZEROTO_AWAY都不会更改其值,同样,在这种情况下,TO_ZERO_05_AWAY也不会更改其值。

>>> from rounders import round_to_zero_05_away
>>> round_to_zero_05_away(1.234, 1)  # behaves like `TO_ZERO`
1.2
>>> round_to_zero_05_away(-1.294, 1)  # also behaves like `TO_ZERO`
-1.2
>>> round_to_zero_05_away(1.534, 1)  # `TO_ZERO` would give 1.5, so round away
1.6
>>> round_to_zero_05_away(-2.088, 1)  # `TO_ZERO` would give -2.0, so round away
-2.1
>>> round_to_zero_05_away(3.5, 1)  # `TO_ZERO` wouldn't change the value; leave as-is
3.5

别名

函数truncfloorceil分别是round_to_zeroround_to_minusround_to_plus的别名。

关于舍入模式的说明

关于特定舍入模式的说明

  • TIES_TO_EVEN有多个名称,包括“银行家舍入”、“统计学家舍入”和“荷兰舍入”。它与Python的默认舍入模式以及IEEE 754的默认舍入模式roundTiesToEven相匹配。许多其他语言也默认使用此舍入模式。

  • TIES_TO_AWAY似乎是学校中最常见的舍入模式,也是用户经常错误地期望round使用的模式。Python 2的round函数使用了此舍入模式。

  • TIES_TO_PLUS 与 JavaScript 的 Math.round 方法使用的舍入模式匹配,并且似乎也是常见的教学方法。(见 ECMA-262,第 13 版。 §21.3.2.28。)

  • TIES_TO_ZERO 在 IEEE 754 的“增强算术运算”中使用。

  • TO_ZEROmath.trunc 的行为相匹配

  • TO_PLUSmath.ceil 的行为相匹配

  • TO_MINUSmath.floor 的行为相匹配

  • TO_ODD 作为一种“重新舍入”的形式,提供了一种避免 双重舍入 现象的方法。假设我们有一个实数 x 和一个位数 p。设 y 是使用 TO_ODD 舍入模式将 x 舍入到 p + 2 位的结果。那么 y 可以作为 x 在舍入到 p 位时的代理,即 yx 将以本模块中定义的任何舍入模式相同的方式进行舍入。(TO_ODD 的二进制类似物在这里更有用——它以相同的方式工作,但只需要两个额外的位来表示中间值,而不是两个额外的数字。)

  • TO_ZERO_05_AWAY 也提供了一种“重新舍入”的形式,但更高效,因为它只需要一个额外的十进制数字,而不是两个。给定一个值 x 和一个位数 p,如果 y = round(x, p + 1, mode=TO_ZERO_05_AWAY),则对于本包中定义的任何十三种舍入模式,round(x, p, mode=mode) == round(y, p, mode=mode)

    >>> from rounders import *
    >>> import random
    >>> x = random.uniform(-1.0, 1.0)
    >>> y = round(x, 5, mode=TO_ZERO_05_AWAY)
    >>> round(x, 4, mode=TO_ZERO) == round(y, 4, mode=TO_ZERO)
    True
    >>> round(x, 4, mode=TIES_TO_ODD) == round(y, 4, mode=TIES_TO_ODD)
    True
    >>> round(x, 4, mode=TO_ZERO_05_AWAY) == round(y, 4, mode=TO_ZERO_05_AWAY)
    True
    

本包中舍入模式与其他舍入模式之间的关系

  • IEEE 754 定义了五个“舍入方向”属性:roundTiesToEvenroundTiesToAwayroundTowardPositiveroundTowardNegativeroundTowardZero。这些分别对应于 TIES_TO_EVENTIES_TO_AWAYTO_PLUSTO_MINUSTO_ZERO。IEEE 754-2019 的“增强算术运算”部分还定义了一个属性 roundTiesToZero,对应于本模块中的 TIES_TO_ZERO

    IEEE 754 舍入方向 rounders 舍入模式
    roundTiesToEven TIES_TO_EVEN
    roundTiesToAway TIES_TO_AWAY
    roundTiesToZero TIES_TO_ZERO
    roundTowardPositive TO_PLUS
    roundTowardNegative TO_MINUS
    roundTowardZero TO_ZERO
  • 截至 Python 3.11,Python 的 decimal 模块定义了八个舍入选项,对应于本模块中的舍入模式如下

    decimal 舍入选项 rounders 舍入模式
    ROUND_CEILING TO_PLUS
    ROUND_DOWN TO_ZERO
    ROUND_FLOOR TO_MINUS
    ROUND_HALF_DOWN TIES_TO_ZERO
    ROUND_HALF_EVEN TIES_TO_EVEN
    ROUND_HALF_UP TIES_TO_AWAY
    ROUND_UP TO_AWAY
    ROUND_05UP TO_ZERO_05_AWAY

支持的数值类型

默认情况下,rounders 支持 Python 的内置数值类型:intfloatdecimal.Decimalfractions.Fraction。底层,它使用 functools.singledispatch 来执行所有类型特定的操作。这应该允许在未来轻松扩展到新的数值类型。扩展机制尚未稳定。

未来方向

未来版本的主要目标

  • 添加格式化支持,包括在格式规范中指定舍入方向的能力。
  • 最终确定并记录添加对自定义类型支持的机制。
  • 改进 round 的性能,特别是对于 float 类型,如果需要,可以通过 C 扩展来实现。
  • 更好地记录将 round 应用于二进制浮点数(特别是对于有方向的舍入模式,其中 round 不是幂等的)的陷阱。

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

rounders-0.2.0.tar.gz (41.4 kB 查看哈希值)

上传时间 源代码

构建分发

rounders-0.2.0-py3-none-any.whl (36.6 kB 查看哈希值)

上传时间 Python 3

支持

AWSAWS云计算和安全赞助商DatadogDatadog监控FastlyFastlyCDNGoogleGoogle下载分析MicrosoftMicrosoftPSF赞助商PingdomPingdom监控SentrySentry错误日志StatusPageStatusPage状态页面