å
说ç»è®ºï¼è¿ä¸ªé®é¢æ¯ç±äºcpythonçå°æ¿é¤è¿ç®ç¬¦ï¼//ï¼çå®ç°ä¸æ¯ æµ®ç¹é¤æ³+floor æ¥å®ç°èæ¯ç¨äºï¼è¢«é¤æ° - ä½æ°ï¼/é¤æ° 导è´çã
PSï¼Jythonä¸å¯ä»¥å¾å°20.0ï¼èPEPéè§å®äºa // båºè¯¥çäºround(a/b)ï¼æ以似ä¹è¿æ¯cpythonå®ç°çä¸ä¸ªbugï¼
é¦å
å
åæä¸1 / 0.05究ç«åºè¯¥çäºå¤å°ãçæ¡å°±æ¯ç²¾ç¡®ç20.0ã
ç®å解éä¸ï¼IEEE754æµ®ç¹æ°è§å®ï¼å¦æä¸ä¸ªæµ®ç¹æ°çå¼ä¸è½è¢«ç²¾ç¡®è®°å½ï¼é£ä¹å®çå¼ä¼è¢«è®°æä¸è¿ä¸ªæ°è·ç¦»æè¿çå¯ä»¥è¢«IEEEæµ®ç¹æ°è¡¨ç¤ºçæ°ã
é¦å
ï¼0.05å¨äºè¿å¶ä¸æ¯æ é循ç¯å°æ°ï¼èªç¶ä¸è½è¢«ç²¾ç¡®è®°å½ï¼å æ¤0.05è¿ä¸ªæµ®ç¹æ°çå®é
å¼æ¯ä¸çäº0.05çï¼å®é
å¼æ¯çº¦ä¸º0.05 + 2.7e-18ã
ä¹ååæµ®ç¹é¤æ³ï¼å®é
ä¸åçæ¯1 / (0.05+2.7...e-18)ï¼è¿ä¸ªé¤æ³çç»æ大约æ¯20 - 1.1e-15ãè¿ä¸ªå¼ä¹ä¸è½è¢«ç²¾ç¡®è¡¨ç¤ºï¼æ°å¥½ç¦»è¿ä¸ªæ°æè¿çå¯ä»¥è¡¨ç¤ºçå¼å°±æ¯20.0ï¼å æ¤å³ä½¿ææµ®ç¹æ°è¯¯å·®ç»æä¹æ¯ç²¾ç¡®ç20.0ã
æ¢ç¶1/0.05å°±æ¯20.0ï¼é£ä¹å¯¹ä»åfloorè¿ç®èªç¶ä¹æ¯20äºã
ç°å¨çé®é¢å°±æ¯ä¸ºä»ä¹1 // 0.05ä¼åæ19.0ï¼è¦è§£å³è¿ä¸ªé®é¢åªè½ç¿»æºç ç//è¿ç®ç¬¦çå®ç°ã
ç´æ¥æcpython/floatobject.c at 829b49cbd2e4b1d573470da79ca844b730120f3d · python/cpython · GitHub ä¸å®ç°//è¿ç®çä¸æ®µè´´ä¸æ¥ï¼
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);
}
å¯ä»¥åç°cpythonä¸x // yçå®ç°å®é
ä¸æ¯
round((x - fmod(x, y)) / y)
ï¼å
¶ä¸fmodå½æ°æ¯æ±ä¸¤ä¸ªæµ®ç¹æ°ç¸é¤çä½æ°ã
è¿æ ·ä¸æ¥å°±è§£éçéäºï¼å¨åè¿å¶ä¸ï¼æ¾ç¶1é¤ä»¥0.05çä½æ°åºè¯¥æ¯0.0ãç¶èå¨IEEEæµ®ç¹æ°ç¯å¢ä¸ï¼0.05çå®é
å¼æ¯çº¦0.05 + 2.7e-18ï¼ç¥å¤§äº0.05ï¼è¿æ ·ä¸æ¥1é¤ä»¥è¿ä¸ªæ°çä½æ°å°±æäºçº¦0.05 - 5e-17ï¼ä»1ä¸åæè¿ä¹å¤ä¹åå°±åªå©0.95äºï¼é¤ä»¥0.05åroundååæ19.0ã
温馨提示:答案为网友推荐,仅供参考