Skip to content
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

Fix integer underflows when rounding up and input is 0 #81277

Conversation

darksylinc
Copy link
Contributor

@darksylinc darksylinc commented Sep 3, 2023

Fixes #80358

Whenever the code wants to round up, it performs x = (x - 1) / y + 1 when it should be doing x = (x + y - 1) / y

The original code when the input is 0 is wrong for both unsigned (produces a very large value) and signed (produces 1 instead of 0).

This version handles 0 properly. (x / y = 0).

Mathematically they're the same:

= (x - 1) / y + 1
= (x - 1) / y + y / y
= (x + y - 1) / y

However in terms of computer science, they're not

@darksylinc darksylinc requested review from a team as code owners September 3, 2023 16:22
// 65 / 64 = 2
//
// Will not work correctly if numerator + denominator - 1u results in an overflow.
static _ALWAYS_INLINE_ uint32_t divide_round_up(uint32_t numerator, uint32_t denominator) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
static _ALWAYS_INLINE_ uint32_t divide_round_up(uint32_t numerator, uint32_t denominator) {
static _ALWAYS_INLINE_ uint32_t divide_round_up(uint32_t p_numerator, uint32_t p_denominator) {

Prefix arguments with p_, same everywhere

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Arg!

My bad.

@AThousandShips
Copy link
Member

Also what is the difference between this and:

Which already does this

Fixes godotengine#80358

Whenever the code wants to round up, it performs x = (x - 1) / y + 1
when it should be doing x = (x + y - 1) / y

The original code when the input is 0 is wrong for both unsigned
(produces a very large value) and signed (produces 1 instead of 0).

This version handles 0 properly. (x / y = 0).

Mathematically they're the same:

= (x - 1) / y + 1
= (x - 1) / y + y / y
= (x + y - 1) / y

However in terms of computer science, they're not
@darksylinc darksylinc force-pushed the matias-integer-underflow-round-up branch from a437278 to e826b64 Compare September 3, 2023 16:27
@Chaosus Chaosus added this to the 4.2 milestone Sep 3, 2023
@darksylinc
Copy link
Contributor Author

Also what is the difference between this and:
#80390
Which already does this

It's very simple: I looked for it and I didn't see it. 🤦‍♂️

I'm closing this one then.

@AThousandShips
Copy link
Member

AThousandShips commented Sep 3, 2023

No worries, thank you for your contribution nontheless!

In the future check the area to the right on an issue, it lists the PRs linked with this :)

@AThousandShips AThousandShips removed this from the 4.2 milestone Sep 3, 2023
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.

Integer underflows throughout the code when trying to round up
3 participants