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

[stdlib] Simplify Int.__floordiv__ and friends #3497

Open
wants to merge 1 commit into
base: nightly
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 12 additions & 29 deletions stdlib/src/builtin/int.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -593,14 +593,11 @@ struct Int(
`floor(self/rhs)` value.
"""
# This should raise an exception
var denominator = select(rhs == 0, 1, rhs)
var div: Int = self._positive_div(denominator)

var mod = self - div * rhs
var div_mod = select(((rhs < 0) ^ (self < 0)) & mod, div - 1, div)
div = select(self > 0 & rhs > 0, div, div_mod)
div = select(rhs == 0, 0, div)
return div
var denom = select(rhs == 0, 1, rhs)
var div = self._positive_div(denom)
var rem = self._positive_rem(denom)
var res = select(((rhs < 0) ^ (self < 0)) & rem, div - 1, div)
return select(rhs == 0, 0, res)

@always_inline("nodebug")
fn __mod__(self, rhs: Int) -> Int:
Expand All @@ -612,16 +609,10 @@ struct Int(
Returns:
The remainder of dividing self by rhs.
"""
var denominator = select(rhs == 0, 1, rhs)
var div: Int = self._positive_div(denominator)

var mod = self - div * rhs
var div_mod = select(((rhs < 0) ^ (self < 0)) & mod, mod + rhs, mod)
mod = select(
self > 0 & rhs > 0, self._positive_rem(denominator), div_mod
)
mod = select(rhs == 0, 0, mod)
return mod
var denom = select(rhs == 0, 1, rhs)
var rem = self._positive_rem(denom)
var res = select(((rhs < 0) ^ (self < 0)) & rem, rem + rhs, rem)
return select(rhs == 0, 0, res)

@always_inline("nodebug")
fn __divmod__(self, rhs: Int) -> Tuple[Int, Int]:
Expand All @@ -631,17 +622,9 @@ struct Int(
rhs: The value to divide on.

Returns:
The quotient and remainder as a `Tuple(self // rhs, self % rhs)`.
"""
if rhs == 0:
return 0, 0
var div: Int = self._positive_div(rhs)
if rhs > 0 & self > 0:
return div, self._positive_rem(rhs)
var mod = self - div * rhs
if ((rhs < 0) ^ (self < 0)) & mod:
return div - 1, mod + rhs
return div, mod
The quotient and remainder as a tuple `(self // rhs, self % rhs)`.
"""
return self // rhs, self % rhs
Copy link
Collaborator

Choose a reason for hiding this comment

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

Question By recomputing things, won't this regress performance a bit?

Copy link
Contributor Author

@soraros soraros Sep 19, 2024

Choose a reason for hiding this comment

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

Both // and % are marked as always_inline and they share most of the code; I just assume that the compiler can see through the defs and do CSE well. I can inline and do a manual dedup if you so prefer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As a ref point, UInt also does this.

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 checked and they generates identical assembly.


@always_inline("nodebug")
fn __pow__(self, exp: Self) -> Self:
Expand Down