[Numpy-tickets] [NumPy] #464: division inconsistent with Python; a/b inconsistent with a%b, scary scalar behaviour

NumPy numpy-tickets@scipy....
Tue Mar 6 11:27:54 CST 2007


#464: division inconsistent with Python;  a/b inconsistent with a%b, scary scalar
behaviour
----------------------------+-----------------------------------------------
 Reporter:  gregsmithto     |       Owner:  somebody
     Type:  defect          |      Status:  new     
 Priority:  normal          |   Milestone:          
Component:  numpy.numarray  |     Version:  1.0.1   
 Severity:  normal          |    Keywords:  division
----------------------------+-----------------------------------------------
 With integer {{{n/d}}} and {{{n%d}}} , if  {{{n <0}}}  and {{{d>0}}} ,
 python always rounds {{{n/d}}}  to -inf and gives {{{0 <= n%d < d}}} ;
 whereas numpy gives you whatever the C division does, which is usually
 rounding towards zero for {{{n/d}}} . I brought this up for Numeric a few
 years ago, and was informed that this had been discussed on the group and
 it was done this way for performance reasons. I would have voted strongly
 the other way, but that is what it is, and it wasn't such a big deal for
 Numeric. However, with numpy, this behaviour is inherited by integers
 extracted from arrays, which otherwise behave like Python ints. These
 objects could travel an arbitrary distance into other parts of a Python
 application which are completely unaware of numpy, so there is the
 potential for very strange failures. Also,  it seems that numpy (unlike
 Numeric) now gives the python result for {{{%}}}, but still gives the C
 result for {{{/}}} (and {{{//}}}).

 So we have:
    * {{{(n/d)*d+(n%d) != n}}}   because {{{/}}} and {{{%}}} are
 inconsistent
    * {{{//}}} operator (which is called 'floor_division' internally), does
 not do floor division
    * very surprising behavior with scalars, as shown below.


 {{{
 >>> from numpy import array
 >>> a,b= -7,10
 >>> a,b
 (-7, 10)
 >>> a/b,  a%b
 (-1, 3)
 >>> divmod(a,b)
 (-1, 3)
 >>> pair=array((a,b))
 >>> pair
 array([-7, 10])
 >>> a,b=pair
 >>> a,b
 (-7, 10)
 >>> a/b,  a%b
 (0, 3)
 >>> divmod(a,b)
 (0, 3)
 }}}

 At least it is now possible to get a future-proof,portable floor division
 without needing conditionals: {{{ (n-(n%d))//d }}}, since the {{{%}}}
 works.

 I recognize the problems associated with changing this behaviour. But it's
 already been changed (I don't know when) for {{{%}}}; and having it
 propogated into the scalars creates a serious new problem which wasn't
 there in Numeric. Also -- at least in principle -- the current behaviour
 is platform dependent, so apps using numpy may encounter the same issue
 simply by moving to a different C compiler platform.

-- 
Ticket URL: <http://projects.scipy.org/scipy/numpy/ticket/464>
NumPy <http://projects.scipy.org/scipy/numpy>
The fundamental package needed for scientific computing with Python.


More information about the Numpy-tickets mailing list