4

Here is a minimal code example:

import numpy as np

x = np.array(1e-35, dtype=np.double)
y = int(1e19)
print( type(x/y) )

y = int(1e20)
print( type(x/y) )

On my machine in the former case it prints numpy.float64, and in the latter case it prints float. I imagine the specific numbers will vary on different machines, but the point is that for small ints the division preserves type, while for large ints the type is cast to a Python float. I would like to know whether this is a bug in Numpy or not, and whether there are any solutions besides manually casting everything to be a double.

It seems harmless, but when I try to write a ufunc and the cast only happens on certain elements of an array, the return type becomes object, and the program throws a "could not be coerced to provided output parameter" error.

1 Answer 1

3

The output type change because int(1e19) can be safely casted to an np.int64 while int(1e20) cannot fit in an np.int64 and thus cannot be safely casted (you can check that with y.bit_length()). As a result, y is first kept as pure-Python object (a variable-sized integer), then Python cast it to a pure-Python float object so the result is a also pure-Python float object too. This happens because Numpy try to apply its own semantics rules based on native types. When it cannot use them (due to unsafe/impossible casts), the fallback pure-Python object-based semantics is applied resulting in pure-Python objects. Still, this appear to be a known issue. You can check related issues and discuss with Numpy developers on GitHub for more information.

I think the best strategy is not to rely on this behaviour. Indeed, when a float-like value is multiplied by a huge integer, the huge integer will always be casted to a float-like value first (because of semantics rules). This cast likely introduces a loss of precision as well as the following multiplication. Thus, I think this is better to cast the huge integer yourself to keep in mind that the integer value may not be perfectly represented.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.