Skip to content

[RFC] Add is_representable_as_float() and is_representable_as_int #19308

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

alexandre-daubois
Copy link
Contributor

@alexandre-daubois alexandre-daubois changed the title Add is_representable_as_float() and is_representable_as_int [RFC] Add is_representable_as_float() and is_representable_as_int Jul 30, 2025
@TimWolla TimWolla added the RFC label Jul 30, 2025
@alexandre-daubois alexandre-daubois force-pushed the is-representable-as-float-int branch 3 times, most recently from 44a9c53 to 7e80d90 Compare July 30, 2025 12:51
#if SIZEOF_ZEND_LONG == 4
return true;
#else
if (lval >= -9007199254740992LL && lval <= 9007199254740992LL) {
Copy link
Member

@arnaud-lb arnaud-lb Jul 30, 2025

Choose a reason for hiding this comment

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

Nit:

Suggested change
if (lval >= -9007199254740992LL && lval <= 9007199254740992LL) {
if (lval >= -(INT64_C(1)<<53) && lval <= INT64_C(1)<<53) {

and similarly for other literals

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It might be outdated if #19308 (comment) is validated 🙂

return true;
}

if (abs_val > 9007199254740992ULL) {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: condition is always true?

return true;
}

zend_ulong abs_val = (zend_ulong)(lval < 0 ? -lval : lval);
Copy link
Member

Choose a reason for hiding this comment

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

This is undefined behavior with lval == ZEND_LONG_MIN

#if SIZEOF_ZEND_LONG == 4
return true;
#else
if (lval >= -9007199254740992LL && lval <= 9007199254740992LL) {
Copy link
Member

Choose a reason for hiding this comment

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

What am I missing? Can't this entire else block just be return (zend_long) (double) lval == lval; ?

Copy link
Member

Choose a reason for hiding this comment

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

Ah I guess UB... Can't we workaround that, the one liner is so much easier and prettier

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I actually changed the function with the oneliner. I also added a test case with PHP_INT_MIN. I think it's actually good? I think the undefined behavior is not relevant anymore with the one-liner as we don't manipulate things manually

@alexandre-daubois alexandre-daubois force-pushed the is-representable-as-float-int branch from 7e80d90 to 7b6ede1 Compare July 31, 2025 07:29
@alexandre-daubois alexandre-daubois force-pushed the is-representable-as-float-int branch from 7b6ede1 to 028761a Compare July 31, 2025 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants