numpy中楼层划分的奇怪结果
Weird result of floor division in numpy
我偶然发现了 np.float32 或 np.float64 的下限除法结果,我不明白
我在 Python 3.6.7
中使用 numpy 1.15.4
>>> import numpy as np
>>> np.float32(0)//1
-0.0
我知道,我可以通过 abs() 等解决方法,但为什么我首先得到的是“-0.0”而不是“0.0”?
我怀疑 numpy 使用 divmod 函数来计算 floor division 并且导致这个的行是 here:
/* if div is zero ensure correct sign */
floordiv = (a / b > 0) ? 0.0@c@ : -0.0@c@;
示例:
>>> a = np.zeros(1)
>>> b = 1
>>> np.where(a/b > 0, 0.0, -0.0)
array([-0.])
Python 的 divmod
函数似乎可以正确处理这个问题,因此他们必须使用不同的算法:
>>> divmod(0.0,1)
(0.0, 0.0)
>>> divmod(-0.0,1)
(-0.0, 0.0)
我对此进行了更多研究,这是当 div 为零(link):
/* div is zero - get the same sign as the true quotient */
floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */
和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);
}
}
所以 python 能够做到这一点而 numpy 不能的原因是 python 使用 atan2()
来区分 -0.0
和 +0.0
.
更新:此问题将在 numpy 的 1.17.0 版本中修复。您可以查看发行说明 here.
我偶然发现了 np.float32 或 np.float64 的下限除法结果,我不明白
我在 Python 3.6.7
中使用 numpy 1.15.4>>> import numpy as np
>>> np.float32(0)//1
-0.0
我知道,我可以通过 abs() 等解决方法,但为什么我首先得到的是“-0.0”而不是“0.0”?
我怀疑 numpy 使用 divmod 函数来计算 floor division 并且导致这个的行是 here:
/* if div is zero ensure correct sign */
floordiv = (a / b > 0) ? 0.0@c@ : -0.0@c@;
示例:
>>> a = np.zeros(1)
>>> b = 1
>>> np.where(a/b > 0, 0.0, -0.0)
array([-0.])
Python 的 divmod
函数似乎可以正确处理这个问题,因此他们必须使用不同的算法:
>>> divmod(0.0,1)
(0.0, 0.0)
>>> divmod(-0.0,1)
(-0.0, 0.0)
我对此进行了更多研究,这是当 div 为零(link):
/* div is zero - get the same sign as the true quotient */
floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */
和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);
}
}
所以 python 能够做到这一点而 numpy 不能的原因是 python 使用 atan2()
来区分 -0.0
和 +0.0
.
更新:此问题将在 numpy 的 1.17.0 版本中修复。您可以查看发行说明 here.