Python内置函数源码-round()

Cod*_*ard 0 python rounding

问题

我想访问内置函数的源代码round(),以允许我创建一个非常相似的函数。我如何访问该源代码以及编辑/使用该源代码的容易程度如何?


round()我对此感兴趣的原因是,即使位数为负,内置函数也会将整数转换为浮点数。例如:

round(1234.5678,-2)
Run Code Online (Sandbox Code Playgroud)

退货

1200.0 
Run Code Online (Sandbox Code Playgroud)

我想创建一个返回整数的函数。我确信还有其他方法可以实现相同的结果,但我想看看内置函数如何实现此任务,因为我希望这是相当有效的。

Sam*_*son 5

只是扩展 Mark Dickinson 的评论并确保我自己理解它,CPythonround函数分布在代码库的多个部分。

\n\n

round(number, ndigits)首先查找并调用__round__对象的方法。这是由bltinmodule.c 中的C 函数实现的builtin_round_impl

\n\n

for floats 这会调用该方法,该方法在floatobject.c:1045 中float.__round__实现,但floatobject.ch中有一个存根入口点,我认为它主要由Python 的参数诊所工具维护。该标头也是其定义为的地方float___round___implPyMethodDefFLOAT___ROUND___METHODDEF

\n\n

C 函数float___round___impl首先检查是否ndigits未指定(即没有传递任何内容,或作为 传递None),在这种情况下,它会round从 C 标准库调用(或从 pymath.c 的版本作为后备)。

\n\n

如果指定了,那么它可能会调用floatobject.c:927 中ndigits的版本。它以 53 位精度工作,因此调整浮点舍入模式,并且通常是相当繁琐的代码,但基本上它将双精度数转换为具有给定精度的字符串,然后转换回双精度数double_round

\n\n

对于少数平台, double_roundfloatobject.c:985的另一个版本可以完成基本上的明显操作round(x * 10**ndigits) / 10**ndigits,但这些额外的操作会降低结果的精度

\n\n

请注意,更高精度的版本将为NumPy中的版本和R中的等效版本提供不同的答案,如此所述。例如,round(0.075, 2)内置 round 的结果为 0.07,而 numpy 和 R 的结果为 0.08。我发现查看正在发生的情况的最简单方法是使用该decimal模块查看浮点数的完整十进制扩展:

\n\n
from decimal import Decimal\n\nprint(Decimal(0.075))\n
Run Code Online (Sandbox Code Playgroud)\n\n

给出:0.0749999999999999972\xe2\x80\xa6,即 0.075 无法用(二进制)浮点数精确表示,并且最接近的数字恰好稍小,因此它向下舍入为 0.07。而numpy 中的实现给出 0.08,因为它实际上是这样做的round(0.075 * 100) / 100,并且中间值恰好向上舍入,即:

\n\n
print(Decimal(0.075 * 100))\n
Run Code Online (Sandbox Code Playgroud)\n\n

精确给出7.5,精确舍入为8

\n