<p dir="auto">When create a numpy array from a list of integers, if some integers are in range [2^63, 2^64) and some integers are in range [0, 2^63), we get a numpy array with <code class="notranslate">dtype=np.float64</code> instead of <code class="notranslate">dtype=np.uint64</code>.</p>
<h3 dir="auto">Reproducing code example:</h3>

<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import numpy as np
import sys

a = np.array([2**63, 2**63 + 1, 2**63 + 2**62])
print(a, a.dtype) # It's ok!

a = np.array([2**63, 2**63 + 1, 2**63 + 2**62, 123456])
print(a, a.dtype) # In this case, a.dtype == np.float64, but we expect np.uint64

a = np.array([2**63, 2**63 + 1, 2**63 + 2**62, 123456], dtype=np.uint64)
print(a, a.dtype) # It's ok!

print(np.__version__, sys.version)"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">numpy</span> <span class="pl-k">as</span> <span class="pl-s1">np</span>
<span class="pl-k">import</span> <span class="pl-s1">sys</span>

<span class="pl-s1">a</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span>, <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>, <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span> <span class="pl-c1">+</span> <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">62</span>])
<span class="pl-en">print</span>(<span class="pl-s1">a</span>, <span class="pl-s1">a</span>.<span class="pl-s1">dtype</span>) <span class="pl-c"># It's ok!</span>

<span class="pl-s1">a</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span>, <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>, <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span> <span class="pl-c1">+</span> <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">62</span>, <span class="pl-c1">123456</span>])
<span class="pl-en">print</span>(<span class="pl-s1">a</span>, <span class="pl-s1">a</span>.<span class="pl-s1">dtype</span>) <span class="pl-c"># In this case, a.dtype == np.float64, but we expect np.uint64</span>

<span class="pl-s1">a</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span>, <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>, <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">63</span> <span class="pl-c1">+</span> <span class="pl-c1">2</span><span class="pl-c1">**</span><span class="pl-c1">62</span>, <span class="pl-c1">123456</span>], <span class="pl-s1">dtype</span><span class="pl-c1">=</span><span class="pl-s1">np</span>.<span class="pl-s1">uint64</span>)
<span class="pl-en">print</span>(<span class="pl-s1">a</span>, <span class="pl-s1">a</span>.<span class="pl-s1">dtype</span>) <span class="pl-c"># It's ok!</span>

<span class="pl-en">print</span>(<span class="pl-s1">np</span>.<span class="pl-s1">__version__</span>, <span class="pl-s1">sys</span>.<span class="pl-s1">version</span>)</pre></div>
<h3 dir="auto">NumPy/Python version information:</h3>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="1.18.5 3.6.9 (default, Jan 26 2021, 15:33:00)
[GCC 8.4.0]"><pre class="notranslate"><code class="notranslate">1.18.5 3.6.9 (default, Jan 26 2021, 15:33:00)
[GCC 8.4.0]
</code></pre></div>
<p dir="auto">When <code class="notranslate">np.array()</code> or <code class="notranslate">.asarray()</code> is used to go from a list of integers, without specifying a dtype explicitly, it can pick default dtypes including int64 &amp; uint64. But there's a strange corner case where it defaults to float64 and loses precision, even though all the values could be uint64. Specfically, this occurs when some but not all values can be int64:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="In [11]: max_int64 = np.iinfo(np.int64).max                                                                            

In [12]: np.array([max_int64]).dtype                                                                                   
Out[12]: dtype('int64')

In [13]: np.array([max_int64 + 1]).dtype                                                                               
Out[13]: dtype('uint64')

In [14]: np.array([max_int64 + 1, max_int64]).dtype                                                                    
Out[14]: dtype('float64')"><pre class="notranslate"><span class="pl-v">In</span> [<span class="pl-c1">11</span>]: <span class="pl-s1">max_int64</span> <span class="pl-c1">=</span> <span class="pl-s1">np</span>.<span class="pl-en">iinfo</span>(<span class="pl-s1">np</span>.<span class="pl-s1">int64</span>).<span class="pl-s1">max</span>                                                                            

<span class="pl-v">In</span> [<span class="pl-c1">12</span>]: <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">max_int64</span>]).<span class="pl-s1">dtype</span>                                                                                   
<span class="pl-v">Out</span>[<span class="pl-c1">12</span>]: <span class="pl-en">dtype</span>(<span class="pl-s">'int64'</span>)

<span class="pl-v">In</span> [<span class="pl-c1">13</span>]: <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">max_int64</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>]).<span class="pl-s1">dtype</span>                                                                               
<span class="pl-v">Out</span>[<span class="pl-c1">13</span>]: <span class="pl-en">dtype</span>(<span class="pl-s">'uint64'</span>)

<span class="pl-v">In</span> [<span class="pl-c1">14</span>]: <span class="pl-s1">np</span>.<span class="pl-en">array</span>([<span class="pl-s1">max_int64</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>, <span class="pl-s1">max_int64</span>]).<span class="pl-s1">dtype</span>                                                                    
<span class="pl-v">Out</span>[<span class="pl-c1">14</span>]: <span class="pl-en">dtype</span>(<span class="pl-s">'float64'</span>)</pre></div>
<p dir="auto">It doesn't depend on the order they're in, and it's not a general consequence of having two values rather than one - two values above this threshold get <code class="notranslate">uint64</code> as I'd expect.</p>
<p dir="auto">Tested on Numpy 1.18.4, Python 3.8.2.</p>
<p dir="auto">Sorry if this has already been discussed; it's a tricky thing to search for. This relates to an issue reported on h5py: <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="619100596" data-permission-text="Title is private" data-url="https://github.com/h5py/h5py/issues/1547" data-hovercard-type="issue" data-hovercard-url="/h5py/h5py/issues/1547/hovercard" href="https://github.com/h5py/h5py/issues/1547">h5py/h5py#1547</a> .</p>