[Numpy-discussion] Oddity with numpy.int64 integer division

David M. Cooke cookedm at physics.mcmaster.ca
Tue Apr 24 16:23:14 EDT 2007


On Apr 23, 2007, at 22:04 , Warren Focke wrote:

> But even C89 required that x == (x/y)*y + (x%y), and that's not the  
> case
> here.

Missed that. You're right. We pull the same trick Python does with %  
so that the sign of x % y agrees with the sign of y, but we don't  
follow Python in guaranteeing floor division. To fix that means  
calculating x % y (as x - (x/y)*y) and checking if the sign is the  
same as y.

This would be a backward incompatible change, but it would restore  
the above invariant, which I think is important. Alternatively, we  
could change the modulo so that the invariant holds, but we don't  
agree with Python in either / or %. Comments?

> On Mon, 23 Apr 2007, David M. Cooke wrote:
>
>> On Apr 23, 2007, at 16:41 , Christian Marquardt wrote:
>>> On Mon, April 23, 2007 22:29, Christian Marquardt wrote:
>>>> Actually,
>>>>
>>>> it happens for normal integers as well:
>>>>
>>>>>>> n = np.array([-5, -100, -150])
>>>>>>> n // 100
>>>>    array([ 0, -1, -1])
>>>>>>> -5//100, -100//100, -150//100
>>>>    (-1, -1, -2)
>>>
>>> and finally:
>>>
>>>>>> n % 100
>>>    array([95,  0, 50])
>>>>>> -5 % 100, -100 % 100, -150 % 100
>>>    (95, 0, 50)
>>>
>>> So plain python / using long provides consistent results across //
>>> and %, but numpy doesn't...
>>
>> Python defines x // y as returning the floor of the division, and x %
>> y has the same sign as y. However, in C89, it is implementation-
>> defined (i.e., portability-pain-in-the-ass) whether the floor or ceil
>> is used when the signs of x and y differ. In C99, the result should
>> be truncated. From the C99 spec, sec. 6.5.5, #6:
>>         When integers are divided, the result of the / operator
>>         is   the   algebraic   quotient  with  any  fractional  part
>>         discarded.76)  If the quotient  a/b  is  representable,  the
>>         expression (a/b)*b + a%b shall equal a.
>>
>> Numpy follows whatever the C compiler decides to use, because of
>> speed-vs.-Python compatibility tradeoff.
>>
>>>
>>>   Christian.
>>>
>>>> On Mon, April 23, 2007 22:20, Christian Marquardt wrote:
>>>>> Dear all,
>>>>>
>>>>> this is odd:
>>>>>
>>>>>>>> import numpy as np
>>>>>>>> fact = 28250000L * 86400L
>>>>>>>> nn = np.array([-20905000L])
>>>>>>>> nn
>>>>>    array([-20905000], dtype=int64)
>>>>>>>> nn[0] // fact
>>>>>    0
>>>>>
>>>>> But:
>>>>>
>>>>>>>> long(nn[0]) // fact
>>>>>    -1L
>>>>>
>>>>> Is this a bug in numpy, or in python's implementation of longs? I
>>>>> would
>>>>> think both should give the same, really... (Python 2.5, numpy
>>>>> 1.0.3dev3725,
>>>>> Linux, Intel compilers...)
>>>>>
>>>>> Many thanks for any ideas / advice,
>>>>>
>>>>>   Christian
>>
>> --
>> |>|\/|<
>> /------------------------------------------------------------------\
>> |David M. Cooke              http://arbutus.physics.mcmaster.ca/dmc/
>> |cookedm at physics.mcmaster.ca
>>
>>
> _______________________________________________
> Numpy-discussion mailing list
> Numpy-discussion at scipy.org
> http://projects.scipy.org/mailman/listinfo/numpy-discussion
>

-- 
|>|\/|<
/------------------------------------------------------------------\
|David M. Cooke              http://arbutus.physics.mcmaster.ca/dmc/
|cookedm at physics.mcmaster.ca

-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
URL: <http://mail.python.org/pipermail/numpy-discussion/attachments/20070424/4b47bc35/attachment.sig>


More information about the NumPy-Discussion mailing list