Rounding to nearest int with numpy.rint() not consistent for .5

后端 未结 7 1404
余生分开走
余生分开走 2020-12-20 11:37

numpy\'s round int doesn\'t seem to be consistent with how it deals with xxx.5

In [2]: np.rint(1.5)
Out[2]: 2.0

In [3]: np.rint(10.5)
Out[3]: 10.0
<         


        
7条回答
  •  借酒劲吻你
    2020-12-20 12:07

    Numpy rounding does round towards even, but the other rounding modes can be expressed using a combination of operations.

    >>> a=np.arange(-4,5)*0.5
    >>> a
    array([-2. , -1.5, -1. , -0.5,  0. ,  0.5,  1. ,  1.5,  2. ])
    >>> np.floor(a)      # Towards -inf
    array([-2., -2., -1., -1.,  0.,  0.,  1.,  1.,  2.])
    >>> np.ceil(a)       # Towards +inf
    array([-2., -1., -1., -0.,  0.,  1.,  1.,  2.,  2.])
    >>> np.trunc(a)      # Towards 0
    array([-2., -1., -1., -0.,  0.,  0.,  1.,  1.,  2.])
    >>> a+np.copysign(0.5,a)   # Shift away from 0
    array([-2.5, -2. , -1.5, -1. ,  0.5,  1. ,  1.5,  2. ,  2.5])
    >>> np.trunc(a+np.copysign(0.5,a))   # 0.5 towards higher magnitude round
    array([-2., -2., -1., -1.,  0.,  1.,  1.,  2.,  2.])
    

    In general, numbers of the form n.5 can be accurately represented by binary floating point (they are m.1 in binary, as 0.5=2**-1), but calculations expected to reach them might not. For instance, negative powers of ten are not exactly represented:

    >>> (0.1).as_integer_ratio()
    (3602879701896397, 36028797018963968)
    >>> [10**n * 10**-n for n in range(20)]
    [1, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
     0.9999999999999999, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
    

提交回复
热议问题