真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

fmod函數(shù)python fmod函數(shù)出錯

為什么Python中//和math.floor運算結(jié)果會不同

先說結(jié)論:這個問題是由于cpython的地板除運算符(//)的實現(xiàn)不是 浮點除法+floor 來實現(xiàn)而是用了(被除數(shù) - 余數(shù))/除數(shù) 導(dǎo)致的。

站在用戶的角度思考問題,與客戶深入溝通,找到濱海新區(qū)網(wǎng)站設(shè)計與濱海新區(qū)網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、國際域名空間、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋濱海新區(qū)地區(qū)。

PS:Jython下可以得到20.0,而PEP里規(guī)定了a // b應(yīng)該等于round(a/b),所以似乎這是cpython實現(xiàn)的一個bug?

首先先分析下1 / 0.05究竟應(yīng)該等于多少。答案就是精確的20.0。

簡單解釋下:IEEE754浮點數(shù)規(guī)定,如果一個浮點數(shù)的值不能被精確記錄,那么它的值會被記成與這個數(shù)距離最近的可以被IEEE浮點數(shù)表示的數(shù)。

首先,0.05在二進(jìn)制下是無限循環(huán)小數(shù),自然不能被精確記錄,因此0.05這個浮點數(shù)的實際值是不等于0.05的,實際值是約為0.05 + 2.7e-18。

之后做浮點除法,實際上做的是1 / (0.05+2.7...e-18),這個除法的結(jié)果大約是20 - 1.1e-15。這個值也不能被精確表示,恰好離這個數(shù)最近的可以表示的值就是20.0,因此即使有浮點數(shù)誤差結(jié)果也是精確的20.0。

既然1/0.05就是20.0,那么對他做floor運算自然也是20了。

現(xiàn)在的問題就是為什么1 // 0.05會變成19.0,要解決這個問題只能翻源碼看//運算符的實現(xiàn)。

直接把cpython/floatobject.c at 829b49cbd2e4b1d573470da79ca844b730120f3d · python/cpython · GitHub 中實現(xiàn)//運算的一段貼上來:

static PyObject *

float_divmod(PyObject *v, PyObject *w)

{

double vx, wx;

double div, mod, floordiv;

CONVERT_TO_DOUBLE(v, vx);

CONVERT_TO_DOUBLE(w, wx);

if (wx == 0.0) {

PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");

return NULL;

}

PyFPE_START_PROTECT("divmod", return 0)

mod = fmod(vx, wx);

/* fmod is typically exact, so vx-mod is *mathematically* an

exact multiple of wx. But this is fp arithmetic, and fp

vx - mod is an approximation; the result is that div may

not be an exact integral value after the division, although

it will always be very close to one.

*/

div = (vx - mod) / wx;

if (mod) {

/* ensure the remainder has the same sign as the denominator */

if ((wx 0) != (mod 0)) {

mod += wx;

div -= 1.0;

}

}

else {

/* the remainder is zero, and in the presence of signed zeroes

fmod returns different results across platforms; ensure

it has the same sign as the denominator. */

mod = copysign(0.0, wx);

}

/* snap quotient to nearest integral value */

if (div) {

floordiv = floor(div);

if (div - floordiv 0.5)

floordiv += 1.0;

}

else {

/* div is zero - get the same sign as the true quotient */

floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */

}

PyFPE_END_PROTECT(floordiv)

return Py_BuildValue("(dd)", floordiv, mod);

}

可以發(fā)現(xiàn)cpython中x // y的實現(xiàn)實際上是

round((x - fmod(x, y)) / y)

,其中fmod函數(shù)是求兩個浮點數(shù)相除的余數(shù)。

這樣一來就解釋的通了:在十進(jìn)制下,顯然1除以0.05的余數(shù)應(yīng)該是0.0。然而在IEEE浮點數(shù)環(huán)境中,0.05的實際值是約0.05 + 2.7e-18,略大于0.05,這樣一來1除以這個數(shù)的余數(shù)就成了約0.05 - 5e-17,從1中減掉這么多之后就只剩0.95了,除以0.05再round后變成19.0。

在python交互模式下,20÷6的余數(shù)怎么表達(dá)?

在 Python 交互模式下,你可以使用模運算符(%)來表示整數(shù)的余數(shù)。例如,要求 20 除以 6 的余數(shù),可以使用如下代碼:

模運算1

這里,20 除以 6 的余數(shù)是 2。

注意,模運算符(%)只能用于求整數(shù)的余數(shù),對于浮點數(shù),它是不適用的。如果要求浮點數(shù)的余數(shù),可以使用內(nèi)置函數(shù) math.fmod()。

例如:

模運算2

這里,函數(shù) math.fmod() 返回了浮點數(shù) 20 除以 6 的余數(shù) 2.0。

python之?dāng)?shù)學(xué)相關(guān)模塊

先來看一下 math 模塊中包含內(nèi)容,如下所示:

接下來具體看一下該模塊的常用函數(shù)和常量。

ceil(x)

返回 x 的上限,即大于或者等于 x 的最小整數(shù)??聪率纠?/p>

floor(x)

返回 x 的向下取整,小于或等于 x 的最大整數(shù)??聪率纠?/p>

fabs(x)

返回 x 的絕對值??聪率纠?/p>

fmod(x, y)

返回 x/y 的余數(shù),值為浮點數(shù)??聪率纠?/p>

factorial(x)

返回 x 的階乘,如果 x 不是整數(shù)或為負(fù)數(shù)時則將引發(fā) ValueError??聪率纠?/p>

pow(x, y)

返回 x 的 y 次冪??聪率纠?/p>

fsum(iterable)

返回迭代器中所有元素的和。看下示例:

gcd(x, y)

返回整數(shù) x 和 y 的最大公約數(shù)。看下示例:

sqrt(x)

返回 x 的平方根??聪率纠?/p>

trunc(x)

返回 x 的整數(shù)部分??聪率纠?/p>

exp(x)

返回 e 的 x 次冪??聪率纠?/p>

log(x[, base])

返回 x 的對數(shù),底數(shù)默認(rèn)為 e??聪率纠?/p>

常量

tan(x)

返回 x 弧度的正切值。看下示例:

atan(x)

返回 x 的反正切值??聪率纠?/p>

sin(x)

返回 x 弧度的正弦值??聪率纠?/p>

asin(x)

返回 x 的反正弦值??聪率纠?/p>

cos(x)

返回 x 弧度的余弦值??聪率纠?/p>

acos(x)

返回 x 的反余弦值??聪率纠?/p>

decimal 模塊為正確舍入十進(jìn)制浮點運算提供了支持,相比內(nèi)置的浮點類型 float,它能更加精確的控制精度,能夠為精度要求較高的金融等領(lǐng)域提供支持。

decimal 在一個獨立的 context 下工作,可以使用 getcontext() 查看當(dāng)前上下文,如下所示:

從上面的結(jié)果中我們可以看到 prec=28,這就是默認(rèn)的精度,我們可以使用 getcontext().prec = xxx 來重新設(shè)置精度。接下來通過具體示例看一下。

基本運算

執(zhí)行結(jié)果:

上面結(jié)果是用了默認(rèn)精度,我們重新設(shè)置下精度再來看一下:

執(zhí)行結(jié)果:

random 模塊可以生成隨機(jī)數(shù),我們來看一下其常用函數(shù)。

random()

返回 [0.0, 1.0) 范圍內(nèi)的一個隨機(jī)浮點數(shù)??聪率纠?/p>

uniform(a, b)

返回 [a, b) 范圍內(nèi)的一個隨機(jī)浮點數(shù)??聪率纠?/p>

randint(a, b)

返回 [a, b] 范圍內(nèi)的一個隨機(jī)整數(shù)??聪率纠?/p>

randrange(start, stop[, step])

返回 [start, stop) 范圍內(nèi)步長為 step 的一個隨機(jī)整數(shù)。看下示例:

choice(seq)

從非空序列 seq 返回一個隨機(jī)元素。 看下示例:

shuffle(x[, random])

將序列 x 隨機(jī)打亂位置??聪率纠?/p>

sample(population, k)

返回從總體序列或集合中選擇的唯一元素的 k 長度列表,用于無重復(fù)的隨機(jī)抽樣??聪率纠?/p>

參考:


分享標(biāo)題:fmod函數(shù)python fmod函數(shù)出錯
URL標(biāo)題:http://weahome.cn/article/dogjssp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部