Issue 1:
Describe the issue:

Dividing (e.g.) (2**64-1) // 3 works as expected if 3 is an int, but produces a float result if 3 is a numpy.int64.

Consequently, the corresponding modulus calculation produces an incorrect result (also float).

This seems to occur just for dividends in the range of 2**63 to 2**64.

Division of int by numpy.int64 should return the correct integer result for the full range of dividend values.

Reproduce the code example:

import numpy

py3 = 3
npy3 = numpy.int64(3)
n1 = 2**64-1
n2 = 2**63+1
n3 = 2**64+2
n4 = 2**63-2
n5 = 2**128-1
n6 = 2**128+2
print(f"n1 // py3 = {n1 // py3}, n1 % py3 = {n1 % py3}, n1 // npy3 = {n1 // npy3}, n1 % npy3 = {n1 % npy3}")
print(f"n2 // py3 = {n2 // py3}, n2 % py3 = {n2 % py3}, n2 // npy3 = {n2 // npy3}, n2 % npy3 = {n2 % npy3}")
print(f"n3 // py3 = {n3 // py3}, n3 % py3 = {n3 % py3}, n3 // npy3 = {n3 // npy3}, n3 % npy3 = {n3 % npy3}")
print(f"n4 // py3 = {n4 // py3}, n4 % py3 = {n4 % py3}, n4 // npy3 = {n4 // npy3}, n4 % npy3 = {n4 % npy3}")
print(f"n5 // py3 = {n5 // py3}, n5 % py3 = {n5 % py3}, n5 // npy3 = {n5 // npy3}, n5 % npy3 = {n5 % npy3}")
print(f"n6 // py3 = {n6 // py3}, n6 % py3 = {n6 % py3}, n6 // npy3 = {n6 // npy3}, n6 % npy3 = {n6 % npy3}")

Error message:

No response

NumPy/Python version information:

1.23.4 3.10.8 (tags/v3.10.8:aaaf517, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)]

Context for the issue:

No response

Issue 2:
EDIT: since this issue has become somewhat of a stand-in for uint64-problems, here's a summary pulled up from the discussion further down:

PS. Here's all the duckies in one neat row:

open related issues (all about uint64 breaking due to casting to float, or closely related): #2524, #2533, #2955, #4151, #5668, #5745, #5746, #7449, #8002, #8809, #8851, #9982, #10148, #10614, #11020, #11801

open related PRs: #8853

closed/duplicate issues (prob. very incomplete): #2523, #7126, #8522, #8986

loosely related (prob. very incomplete): #2899, #10322, #10982, #11485, #12660

There's a range of values of class np.uint64 that fail a trivial comparison test: v > v - 1

The issue is IMO that it effectively uses float-logic of some kind in the background, which is obviously neither desirable nor necessary.

Reproducing code example:

The following comparisons should all return True:

>>> import numpy as np
>>> for v in np.logspace(50, 63.9, num=20, base=2):
... v = int(v)
... c = np.array([v], dtype='uint64').max() > v - 1
... print(c, v)
...
True 1125899906842624
True 1869506547705232
True 3104232188555715
True 5154439010814696
True 8558715940823230
False 14211365854171536
False 23597338764077220
False 39182327895891032
False 65060506809279480
False 108030067981851424
False 179379106627232000
False 297851001073046464
False 494568294537084288
False 821208581069482368
False 1363580199279397888
False 2264164065900722176
False 3759543384412024832
False 6242554005755503616
True 10365482328612339712
True 17211420807207079936

The way I encountered this, is that 'uint64' is the default dtype for values between np.iinfo('int64').max + 1 and np.iinfo('uint64').max (which makes sense), but leads to the following problem:

>>> v = np.iinfo('int64').max
>>> np.array([v + 1]) > v
array([ True])
>>> np.array([v + 1]).max() > v
False
>>> np.array([v + 1000]).max() == v
True

Numpy/Python version information:

Numpy version: 1.15.4

Python version: 3.6.6 (conda-forge)