Skip to content

Conversation

@serhiy-storchaka
Copy link
Member

@serhiy-storchaka serhiy-storchaka commented Dec 22, 2025

When comparing negative non-integer float and int with the same number of bits in the integer part, __neg__() in the int subclass returning not an int caused an assertion error.

Now the integer is no longer negated. Also, reduced the number of temporary created Python objects.

When comparing negative non-integer float and int with the same number
of bits in the integer part, __neg__() in the int subclass returning
not an int caused an assertion error.

Now the integer is no longer negated. Also, reduced the number of
temporary created Python objects.
Copy link
Contributor

@skirpichev skirpichev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach looks better for me. Few minor nits.

/* Convert w to a double if it fits. In particular, 0 fits. */
int64_t nbits64 = _PyLong_NumBits(w);
assert(nbits64 >= 0);
assert(!PyErr_Occurred());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks useless.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It checks that _PyLong_NumBits() does not fail. It newer fails now.

Comment on lines 474 to 476
if (vsign < 0) {
op = Py_GT; // v >= w <=> trunc(v) > w
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps, it might worth to do sign canonicalization, as before, to get rid of such cases. But I think we have to expose long_neg() for this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will only remove 2 of 6 cases and simplify other 2. The code for negation of both arguments is more complex.

We could also use two tables, this would make the code smaller: op = table[vsign > 0][op].

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was not just to reduce number of lines, but make algorithm more clear. Though, now I'm not sure we gain too much. I'm happy with current code.

@serhiy-storchaka
Copy link
Member Author

@tim-one, could you please look at it? It was originally your code, 307fa78 (bpo-513866/gh-36040).

@skirpichev
Copy link
Contributor

CC @vstinner, maybe you could look too?

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The change removes the PyNumber_Negative() call.

@serhiy-storchaka serhiy-storchaka merged commit 66bca38 into python:main Jan 9, 2026
50 checks passed
@miss-islington-app
Copy link

Thanks @serhiy-storchaka for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14.
🐍🍒⛏🤖

@serhiy-storchaka serhiy-storchaka deleted the float-int-mixed-compare branch January 9, 2026 17:06
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Jan 9, 2026
…ythonGH-143084)

When comparing negative non-integer float and int with the same number
of bits in the integer part, __neg__() in the int subclass returning
not an int caused an assertion error.

Now the integer is no longer negated. Also, reduced the number of
temporary created Python objects.
(cherry picked from commit 66bca383bd3b12d21e879d991d77b37a4c638f88)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@miss-islington-app
Copy link

Sorry, @serhiy-storchaka, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 66bca383bd3b12d21e879d991d77b37a4c638f88 3.13

@bedevere-app
Copy link

bedevere-app bot commented Jan 9, 2026

GH-143623 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.14 bugs and security fixes label Jan 9, 2026
serhiy-storchaka added a commit to serhiy-storchaka/cpython that referenced this pull request Jan 9, 2026
…d int (pythonGH-143084)

When comparing negative non-integer float and int with the same number
of bits in the integer part, __neg__() in the int subclass returning
not an int caused an assertion error.

Now the integer is no longer negated. Also, reduced the number of
temporary created Python objects.
(cherry picked from commit 66bca38)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
@bedevere-app
Copy link

bedevere-app bot commented Jan 9, 2026

GH-143624 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.13 bugs and security fixes label Jan 9, 2026
serhiy-storchaka added a commit that referenced this pull request Jan 9, 2026
…H-143084) (GH-143623)

When comparing negative non-integer float and int with the same number
of bits in the integer part, __neg__() in the int subclass returning
not an int caused an assertion error.

Now the integer is no longer negated. Also, reduced the number of
temporary created Python objects.
(cherry picked from commit 66bca38)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
serhiy-storchaka added a commit that referenced this pull request Jan 9, 2026
…H-143084) (GH-143624)

When comparing negative non-integer float and int with the same number
of bits in the integer part, __neg__() in the int subclass returning
not an int caused an assertion error.

Now the integer is no longer negated. Also, reduced the number of
temporary created Python objects.
(cherry picked from commit 66bca38)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants