簡體   English   中英

Python內置函數源代碼-round()

[英]Python built-in function source code - round()

問題

我想訪問源代碼的內置函數round() ,以允許我創建一個非常相似的函數。 我如何訪問此源代碼,以及如何輕松編輯/使用?


我對此感興趣的原因是,即使數字位數為負,內置函數round()也會將整數轉換為浮點數。 例如:

round(1234.5678,-2)

退貨

1200.0 

我想創建一個返回整數的函數。 我確信還有其他方法可以達到相同的結果,但是我想看看內置函數是如何完成此任務的,因為我希望這樣做會相當有效。

來源似乎是: https : //github.com/python/cpython/blob/master/Python/pymath.c

double
round(double x)
{
    double absx, y;
    absx = fabs(x);
    y = floor(absx);
    if (absx - y >= 0.5)
        y += 1.0;
    return copysign(y, x);
}

其中copysign是:

double
copysign(double x, double y)
{
    /* use atan2 to distinguish -0. from 0. */
    if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) {
        return fabs(x);
    } else {
        return -fabs(x);
    }
}

只是擴展了Mark Dickinson的注釋,並確保我自己理解該注釋,所以CPython round函數分布在代碼庫的多個部分。

round(number, ndigits)從查找並在對象上調用__round__方法開始。 這是由C函數實現builtin_round_impl在bltinmodule.c

對於float s此調用float.__round__方法,這是在實施float___round___impl在floatobject.c:1045 ,但有一個短線切入點floatobject.ch ,我認為主要是維護Python的說法診所工具。 此標頭也是其PyMethodDef定義為FLOAT___ROUND___METHODDEF

C函數float___round___impl首先檢查是否未指定ndigits (即未傳遞或以None傳遞),在這種情況下,它將從C標准庫(或從pymath.c獲得的版本作為回退)調用round

如果ndigits指定,那么它可能調用的版本double_round在floatobject.c:927 它以53位精度工作,因此可以調整浮點舍入模式,並且通常是很漂亮的代碼,但是基本上,它將雙精度數轉換為具有給定精度的字符串,然后再轉換回雙精度數

對於少數平台 ,floatobject.c:985 還有另一個double_round版本,可以完成基本上為round(x * 10**ndigits) / 10**ndigits ,但是這些額外的操作會降低結果的精度

注意,精度更高的版本將在版本給出不同的答案與NumPy和等效版本[R ,作為評論在這里 例如, round(0.075, 2)使用內置回合生成0.07,而numpy和R給出0.08。 我發現最簡單的方法是使用decimal模塊查看浮點數的完整十進制擴展:

from decimal import Decimal

print(Decimal(0.075))

給出: 0.0749999999999999972… ,即0.075不能用(二進制)浮點數精確表示,並且最接近的數字恰好稍小一些,因此將其舍入為0.07。 numpy中實現給出0.08,因為它有效地進行了round(0.075 * 100) / 100並且中間值恰好四舍五入,即:

print(Decimal(0.075 * 100))

給出7.5 ,精確到8

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM