Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Curious Modulus Operator (%) Result

Tags:

python

numpy

What's going on here?

>>> a = np.int8(1)
>>> a%2
1
>>> a = np.uint8(1)
>>> a%2
1
>>> a = np.int32(1)
>>> a%2
1
>>> a = np.uint32(1)
>>> a%2
1
>>> a = np.int64(1)
>>> a%2
1
>>> a = np.uint64(1)
>>> a%2
'1.0'

We suddenly get what appears to be a a string containing the float 1.0!?

>>> a = np.uint64(1)
>>> type(a%2)
<type 'numpy.float64'>

...though it turns out it's simply a float.

What's the philosophy behind this?

I understand that numpy wants to be stricter about things like types and typing rules in order to be more efficient than basic python, but in this case the downsides of returning a very unexpected result to the user (likely breaking their program) seems to far outweigh the slight increase in cost of just checking the sign of the modulus before wandering down this slippery path.

It's not too rare to be working with uint64 values. For example, if you ever load an image into a numpy int array and then sum it, you have uint64(s). On the other hand, it's extremely rare to ever mod anything by a negative number (I've never done it except to see what would happen), because you generally mod things you can count such as indices, and different languages/standards/libraries can each have their own idea of what the result should be.

All this put together leaves me rather confused.

like image 314
Apollys supports Monica Avatar asked May 25 '18 01:05

Apollys supports Monica


People also ask

What is modulus operator with an example?

The modulus operator (also informally known as the remainder operator) is an operator that returns the remainder after doing an integer division. For example, 7 / 4 = 1 remainder 3. Therefore, 7 % 4 = 3. As another example, 25 / 7 = 3 remainder 4, thus 25 % 7 = 4.

How does modulus operator work?

The modulo division operator produces the remainder of an integer division. produces the remainder when x is divided by y. Return Value: If y completely divides x, the result of the expression is 0.

How does modulus work in C#?

In C#, the modulus operator (%) is an operator that is meant to find the remainder after dividing the first operand (the first number) by the second. Remember, the modulus calculates the remainder that is a result of the first operand being divided by the second — it's not meant to solve the division equation.

What is modulus operator in Python?

The % symbol in Python is called the Modulo Operator. It returns the remainder of dividing the left hand operand by right hand operand. It's used to get the remainder of a division problem. The modulo operator is considered an arithmetic operation, along with + , - , / , * , ** , // . The basic syntax is: a % b.


1 Answers

We suddenly get what appears to be a a string containing the float 1.0!?

This is still a float64 - it just looks weird due to a bug in numpy 1.14.3, which is fixed in 1.15.0-dev.

You'd normally thing that there are only two ways to convert to a string - __repr__ (tp_repr), and __str__ (tp_str).

It turns out that in python 2, there's one more - tp_print. This is only called when outputting directly to the console or the interpreter.

It turns out we implemented this wrong for only the interpreter. It's pretty tricky to test interpreter behavior in the test suite!

though it turns out it's simply a float.

This is sort of by design - 2 is inferred to be np.int64(2), and coercing {int64, uint64} -> float64 (to not cause truncation). There are numerous issues about this, but it's tricky to fix.

like image 126
Eric Avatar answered Oct 22 '22 02:10

Eric