Skip to content

BUG: Make mixed integer and floating-point comparisons exact - #32157

Draft
abdulm5 wants to merge 2 commits into
numpy:mainfrom
abdulm5:agent/exact-int-float-comparisons
Draft

abdulm5 wants to merge 2 commits into
numpy:mainfrom
abdulm5:agent/exact-int-float-comparisons

Conversation

@abdulm5

@abdulm5 abdulm5 commented Jul 30, 2026

Copy link
Copy Markdown

PR summary

Closes #32071.

Comparisons between NumPy integers and real floating-point values currently
use common-dtype promotion. When the floating-point dtype cannot represent
every value of the integer dtype, that promotion can round the integer before
the comparison. For example, np.int64(2**53 + 1) can compare equal to
np.float64(2**53), even though the two scalars have different hashes.

This PR:

  • adds exact mixed comparison loops for signed and unsigned 64-bit integers
    against double and long-double values, in both operand orders and for all six
    comparison operations;
  • routes legacy ufunc resolution, modern DType promotion, and NumPy scalar
    rich comparisons through those loops when the integer precision exceeds the
    floating-point mantissa;
  • preserves scalar-subclass comparison overrides;
  • covers representability boundaries, fractional values, signed zero, NaN,
    infinities, both operand orders, scalar and array calls, and the
    equality/hash invariant; and
  • makes existing tests explicit where their expected values previously relied
    on lossy mixed integer/floating-point comparison.

After this change:

>>> a = np.int64(2**53 + 1)
>>> b = np.float64(2**53)
>>> a == b
np.False_
>>> a > b
np.True_

Validation performed locally:

  • spin build --clean -j 4
  • spin test --no-build -- -q: 47,470 passed
  • spin test -m full --no-build -- -q: 50,812 passed; the only remaining
    case was denied POSIX shared-memory access by the sandbox and passed when
    rerun outside the sandbox
  • spin lint
  • git diff --check
  • direct reproduction of BUG: numpy int64/float64 comparisons are inexact #32071 and randomized comparisons against Python
    semantics

First time committer introduction

Hi, this is my first contribution to NumPy. I worked on #32071 to make mixed
integer/floating-point comparisons follow Python's exact comparison semantics
and preserve the equality/hash contract.

AI Disclosure

OpenAI Codex was used to investigate the comparison dispatch paths, generate
the C, C++, and Python implementation changes, add and adapt tests, and run
local validation. I reviewed all generated and AI-assisted changes, understand
the implementation and tests, and take responsibility for this contribution.

Use exact mixed comparison loops when floating-point promotion would lose integer precision. Closes numpy#32071.
@abdulm5
abdulm5 marked this pull request as ready for review July 30, 2026 23:16
@ngoldbaum

ngoldbaum commented Jul 31, 2026 •

Copy link
Copy Markdown
Member

Just a head’s up that I did a very brief history skim to come to the conclusion that this is worth doing. There are very real backward compatibility concerns someone will need to sort through before we can review this. I’d like you to go through history and figure out why this was excluded from the NumPy 1.25 change that fixed #12525 . Should we generate deprecation warnings? How do we do that performantly and without noisily generating unnecessary warnings?

@ngoldbaum

Copy link
Copy Markdown
Member

I marked this as draft to indicates that we still need design work before merging a change like this.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: numpy int64/float64 comparisons are inexact

2 participants