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

Add rem_floor and rem_ceil #108193

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

Conversation

clarfonthey
Copy link
Contributor

@clarfonthey clarfonthey commented Feb 17, 2023

Since rem_ceil is awkward for unsigned integers, I've put it under a separate feature flag, although the result is still in the same tracking issue.

I also removed the rhs > 0 check on the unsigned div_ceil since it's not necessary, and can be a bit confusing to readers. (The only alternative would be rhs = 0, which would panic before reaching this point.)

cc #88581

@rustbot
Copy link
Collaborator

rustbot commented Feb 17, 2023

r? @scottmcm

(rustbot has picked a reviewer for you, use r? to override)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Feb 17, 2023
@rustbot
Copy link
Collaborator

rustbot commented Feb 17, 2023

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

Copy link
Member

@jhpratt jhpratt left a comment

Choose a reason for hiding this comment

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

Setting aside my lack of understanding on the use case, the implementation looks good to me.

@leonardo-m
Copy link

Setting aside my lack of understanding on the use case,

What's a use case of this?

@jhpratt
Copy link
Member

jhpratt commented Feb 18, 2023

I don't know…that's the point. But let's keep discussion of that in #88581.

@rust-log-analyzer

This comment has been minimized.

@clarfonthey
Copy link
Contributor Author

(FWIW I don't understand the docs error: I did define isize::rem_ceil so I don't know why it fails to link.)

@scottmcm
Copy link
Member

r? joshtriplett
As a team member and the same person assigned to #94455

@rustbot rustbot assigned joshtriplett and unassigned scottmcm Feb 18, 2023
@clarfonthey clarfonthey force-pushed the rounding-remainders branch 2 times, most recently from 28d0fc4 to d7600dc Compare March 22, 2023 05:45
@clarfonthey
Copy link
Contributor Author

(I decided to replace the link with a manual one so that it would pass the tests. No idea why it's failing otherwise.)

@workingjubilee workingjubilee added the T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. label Jul 26, 2023
@joshtriplett joshtriplett added S-waiting-on-ACP Status: PR has an ACP and is waiting for the ACP to complete. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 15, 2023
@joshtriplett
Copy link
Member

The code looks fine here, assuming we're prepared to accept these from an API point of view. Given the questions expressed about use case, could you please file an ACP on these methods, specifically? (And since it came up in int_roundings, please do include use case information for unsigned and signed separately, since it's possible that one may be more supported than the other.)

@scottmcm
Copy link
Member

Pondering: would who wants a consistent div and rem result would pair div_floor with rem_ceil?

That would look odd to me when reviewing, but it's also correct if rem_ceil means ceil(a % b), I think?

Thus maybe it would be nice to have merged versions of these, so you get both the quotient and the remainder in one call, with a consistent rounding direction for both.

@clarfonthey
Copy link
Contributor Author

I'd be more than happy to write up an ACP for this, although it's worth clarifying that I did include use cases in the original tracking issue: #88581 (comment)

Ceiling remainder of unsigned integers is the one that I would consider weird and difficult to use, since it's asymmetrical: the remainder of ceiling division is always negative or zero, meaning that you have to return the absolute value of the result instead, or fail on non-exact division.

It's incredibly important and worth repeating: integer division and remainder always come in pairs. Yes, there are a lot of cases where you just throw out the remainder because you're wanting to round something, but I feel like the terms "division" and "remainder" gives a lot of clarity into the sorts of operations that would use these for: you're dividing something into a series of pieces, and even if you often toss out the "remainder," there's still the opportunity to make use of it. While we often abstract division as part of other operations (like averaging), it's good to remember what it actually physically represents.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@Dylan-DPC
Copy link
Member

@clarfonthey i think you would still need an ACP for this

@clarfonthey
Copy link
Contributor Author

From previous experience with ACPs, these are only for new features, and adding onto existing features is mostly what tracking issues are for. I would be happy to write up an ACP for rem_ceil since, as previously mentioned, it only makes sense for signed integers, but I think that rem_floor is reasonable to add for both.

///
/// ## Overflow behavior
///
/// On overflow, this function will panic if overflow checks are enabled (default in debug
Copy link
Contributor

Choose a reason for hiding this comment

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

Signed % always panics on overflow (MIN / -1) regardless of the overflow checks compile option. At least this particular method will panic iff the % inside it panics. Therefor, the documentation is incorrect. The already merged ceil and floor div functions should be double checked with this in mind.

Once that is fixed I suggest explaining exactly what constitutes an overflow. (The remainder function never truly overflows, but it panics whenever the corresponding division would also panic.)

Copy link
Contributor

Choose a reason for hiding this comment

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

The already merged ceil and floor div functions should be double checked with this in mind.

Submitted a PR for that and some other stuff. #119726

@joshtriplett
Copy link
Member

r? libs-api

Copy link
Member

@dtolnay dtolnay left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

I read most of the comments in #88581.

I am on board with signed rem_floor and signed rem_ceil, but not unsigned rem_floor and unsigned unsigned_rem_ceil. Would you like to remove those from this PR and I can merge it, or make one more attempt at synthesizing the rationale in favor of having the entire set?

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 5, 2024
@clarfonthey
Copy link
Contributor Author

Is there a particular reason you're against unsigned rem_floor? I know that it's equivalent to the default, but we already have unsigned div_floor, which is also the default, so, I'm not sure why remainder specifically should be excluded.

In terms of unsigned rem_ceil-- yes, I agree that this one is shaky, which is why I put it under a separate flag. I still think that it could be useful, and I'll put an explanation below, but if you'd rather not even do it then, I can remove it.

As I've said (and I sound like a broken record because I do genuinely believe this), a majority of cases that use division have a parallel case where the remainder could also be useful. For example, if you use div_ceil to round up a percentage bar, you could use rem_ceil when the rounding error makes the bar 100% to alternatively show the number of items remaining. Or, instead of deciding how many tasks are "left over" when dividing tasks among workers using flooring division, you could use ceiling division to get the number of no-op tasks to add to the list so it divides evenly.

Again, I agree that a lot of these fall into "but you could technically do it another way," but the primary goal of offering flooring and ceiling division was to make the intent of algorithms clearer, and I think offering remainders to all the division operators fits that, even if some are just identical to truncating division, and even if rem_ceil has to be negated in the unsigned case.

@dtolnay
Copy link
Member

dtolnay commented Apr 5, 2024

it's equivalent to the default, but we already have unsigned div_floor, which is also the default

I am going to be proposing for unsigned div_floor to be removed.

@clarfonthey
Copy link
Contributor Author

I see. I'm not sure I like that approach since it does go against some of the other philosophies from the standard library-- for example, date algorithms are mentioned as a common case for div_floor, and switching from a signed timestamp to an unsigned timestamp would mean you have to change all the div calls, and vice/versa. I get if the standard library preferred not having "trivial" methods like these but it does have a lot of them.

@bors
Copy link
Contributor

bors commented Jun 30, 2024

☔ The latest upstream changes (presumably #127133) made this pull request unmergeable. Please resolve the merge conflicts.

@rustbot
Copy link
Collaborator

rustbot commented Jul 1, 2024

Some changes occurred in src/tools/cargo

cc @ehuss

@rust-log-analyzer

This comment has been minimized.

@clarfonthey
Copy link
Contributor Author

That error is… very weird. I get it locally too, but not when I switch to the master branch, despite… nothing related being changed? I'm hoping it's a weird error that gets fixed and I can rebase on a newer commit that fixes it.

@ehuss
Copy link
Contributor

ehuss commented Jul 1, 2024

It looks like you updated all the submodules. You should amend your commit and remove those.

@clarfonthey
Copy link
Contributor Author

Huh, I had done a git diff but for some reason they didn't show up when I checked. I've fixed that.

@Dylan-DPC Dylan-DPC added needs-acp This change is blocked on the author creating an ACP. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-ACP Status: PR has an ACP and is waiting for the ACP to complete. labels Jul 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
needs-acp This change is blocked on the author creating an ACP. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.