uint64 converted silently to float64 when adding an int
See original GitHub issueThis code
import numpy
a = numpy.zeros(1, dtype = numpy.uint64)[0]
print(type(a))
i = 1
print(type(i))
a += i
print(type(a))
prints
<class 'numpy.uint64'>
<class 'int'>
<class 'numpy.float64'>
which was a big surprise for me. Why would adding an integer to uint64 result in a floating point value?
Issue Analytics
- State:
- Created 8 years ago
- Reactions:12
- Comments:22 (12 by maintainers)
Top Results From Across the Web
How to change a float64 number to uint64 in a right way?
The problem is not with the conversion but that the number is too large an integer to be stored exactly as a float64...
Read more >Cannot use -a (type int) as type float64 in function argument
Hi everyone, I'm getting this error: Cannot use -a (type int) as type float64 in function argument. Code: package main import (
Read more >Survey of Rounding Implementations in Go - Cockroach Labs
The conversion of v (a float64) to uint64 is not well defined and works differently on amd64 and arm. While fixing the arm...
Read more >pandas: Cast DataFrame to a specific dtype with astype()
uint64, u8, 64-bit unsigned integer. float16, f2, 16-bit floating-point number. float32, f4, 32-bit floating-point number. float64, f8 ...
Read more >Integers and Floating-Point Numbers - Julia Documentation
For example, 1 is an integer literal, while 1.0 is a floating-point ... Int Int32 julia> UInt UInt32 # 64-bit system: julia> Int...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Might be a bit of a radical suggestion, but what about dropping support for uint64 alltogether? Who needs whole numbers between
2**63
and2**64
anyways?This would mean that accumulative type inflation of integers would converge to int64 instead of float64. Information would not be lost silently (nor would there be need for an error)
Fast forward a few years from the last comment on this issue, and I’m curious if there is now any interest from the NumPy core developers in considering a change to the overall type casting behavior of
uint64 + int64 => float64
.Fundamentally, there are two differently problematic approaches to deal with typing a fixed maximum integer size (assuming you don’t want to deal with value-dependent typing):
uint64
toint64
by making the resultint64
.uint64
toint64
by making the resultfloat64
.Option 2 is what NumPy does (and implicitly Javascript, which doesn’t distinguish between ints and floats with its Number type) and Option 1 is what C, C++ and many other languages do. (It is unfortunate that signed overflow is undefined in C, but it is well-defined in many other languages, like Java, Rust and Julia.)
Beyond Option 1 being more intuitive for anyone familiar with integer arithmetic in other languages, I think the fact that NumPy no longer accepts floats as array indices (with good reason!) makes Option 2 even more problematic as users can accidentally compute a float index when combining two integer indices. This problem also pops up in Numba (where we attempt to mimic NumPy casting rules), making it unwise for us to use unsigned ints for things like ranges because they will accidentally create floats when combined with other integer values and cause compilation errors. Other efforts to compile user code written against the NumPy API will also face this question.
Additionally, the current approach seems kind of ad-hoc and inconsistent, given that the far more common
int64 + int64
has a similar overflow issue, yet this case is not cast into a float64.Given how long this behavior has been in place, it may be impractical to change, but if it were in principle possible, would people be in favor of
uint64 + int64 => int64
?