-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Tracking Issue for Integer::{ilog,ilog2,ilog10} #70887
Comments
Having those as const fn is going to be useful to initialize constants, etc. |
Another idea for the naming bikeshed: |
@hanna-kruppe This was brought up before, and was addressed in #70835 (comment):
Does this make sense, or do you feel there is still missing something? |
I am aware of that exchange, it gives one of the reasons for preferring floor semantics that I was referring to. I don't disagree with that being the chosen behavior, I just think making it explicit in the name would be helpful sometimes and not cause any harm otherwise. While it's true that all the methods in |
Regarding naming: I'm in favour of EDIT: Also C99 https://en.cppreference.com/w/c/numeric/math and C++11 https://en.cppreference.com/w/cpp/numeric/math apparently also have |
Regarding naming: I'm fine with |
@scottmcm On the other hand, floating-point numbers currently have |
There are no other functions like |
@scottmcm This was brought up before in the PR. Reiterating my reasoning here:
I think @tspiteri correctly points out that there doesn't appear to be a precedent for float-based operations on integers in the stdlib. But there is a precedent for integer-based operations on floats, suffixed with However if we think people might wonder what kind of log operation this is, we could perhaps spell out in the documentation that this is indeed "integer logarithm". |
@yoshuawuyts Are there any other functions for integers and floats with the same name, but return different results? |
@EdorianDark yes, as I mentioned in an earlier comment multiplication ( assert_eq!((5.0 / 2.0) * 2.0, 5.0); // {mul, div} for floats
assert_eq!((5 / 2) * 2, 4); // {mul, div} for ints |
@yoshuawuyts Yes am aware that the operators behave differently. |
@EdorianDark The same statement I shared above could be written as: use std::ops::{Div, Mul};
assert_eq!(5_u32.div(2).mul(2), 4); // {mul, div} for ints
assert_eq!(5_f32.div(2.0).mul(2.0), 5.0); // {mul, div} for floats We can observe the same methods being called with the same inputs yielding different results because one operates on floats, and the other on ints. Integers and floats have inherently different behavior which means there are many other examples possible -- but the div/mul example is a simple way to convey this. The overarching point I'm trying to make with this example is that |
What about voting for the name in internals.rust-lang.org/ ? |
The functions Maybe lets looks at what other languages do for
Is there any example to call the integer logarithm |
@EdorianDark I'm glad we can agree these methods have the same names but behave differently. Similar examples could be written for non-trait based methods such as
@EdorianDark I think this is something worth exploring (and we already have, but to a lesser extent), but in this context it feels like a moving of the goal posts. But sure, let's take a look:
These methods are different from Rust in several ways:
In contrast Rust has the benefit of clear module hierarchies, operations scoped to their number types, and no implicit casting. The examples would be more relevant if they exposed int logarithms or were methods on numbers. But so far what we're discussing in this thread seems quite different. So far the only plausible reason for naming these methods anything other [1]: C++ shows |
For operators like The logarithm is a continuous function defined on all positive real numbers. The examples I listed show, that the expectation for In Rust there is now the possibility to let |
I'd argue for not using just |
Integer division doesn't really have the same naming issue as integer logarithm, since there are quite a few other programming languages where integer division uses the same operator as float division (C, C++, Java, etc.) so is much less of a learning obstacle. |
The original PR was never merged, which means that this isn't tracking anything at the moment. Closing this for now. |
The original PR was approved by the libs team, but when attempting to merge failed on bors. I've re-filed the PR in #80918 which include a fix which should make the failing tests pass. Apologies for not doing this sooner; going from |
@rust-lang/libs-api can we start an FCP on this? There are no blocking concerns; all we're missing is one more checkmark from a libs-api team member on #70887 (comment). Thanks! |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. |
Stabilize integer logarithms Stabilizes feature `int_log`. I've also made the functions const stable, because they don't depend on any unstable const features. `rustc_allow_const_fn_unstable` is just there for `Option::expect`, which could be replaced with a `match` and `panic!`. cc `@rust-lang/wg-const-eval` closes rust-lang#70887 (tracking issue) ~~blocked on FCP finishing: rust-lang#70887 (comment) FCP finished: rust-lang#70887 (comment)
Stabilize integer logarithms Stabilizes feature `int_log`. I've also made the functions const stable, because they don't depend on any unstable const features. `rustc_allow_const_fn_unstable` is just there for `Option::expect`, which could be replaced with a `match` and `panic!`. cc ```@rust-lang/wg-const-eval``` closes rust-lang#70887 (tracking issue) ~~blocked on FCP finishing: rust-lang#70887 (comment) FCP finished: rust-lang#70887 (comment)
Stabilize integer logarithms Stabilizes feature `int_log`. I've also made the functions const stable, because they don't depend on any unstable const features. `rustc_allow_const_fn_unstable` is just there for `Option::expect`, which could be replaced with a `match` and `panic!`. cc ``@rust-lang/wg-const-eval`` closes rust-lang/rust#70887 (tracking issue) ~~blocked on FCP finishing: rust-lang/rust#70887 (comment) FCP finished: rust-lang/rust#70887 (comment)
rust-lang/rust#100332 The above MR replaces `log10` and friends with `ilog10`; this is the first time an unstable feature bit us in a substantially backwards-incompatible way that's a pain to deal with. Fortunately, I'm just not going to deal with it: this is used with the diagnostic system, which isn't yet used by our projects (outside of me testing), and so those builds shouldn't fail before people upgrade. This is now pending stabalization with the new name, so hopefully we're good now: rust-lang/rust#70887 (comment)
@jhpratt, it was interesting to see your comment. For information, I wasn't aware of this discussion. I needed a fast Little clarifications:
Feel free to use the code if you like, but I understand from earlier comments that the algorithm with corrective tables is not desired. |
Panic for invalid arguments of `{integer primitive}::ilog{,2,10}` in all modes Decision made in rust-lang/rust#100422 (comment) resolves rust-lang/rust#100422 tracking issue: rust-lang/rust#70887 r? `@m-ou-se`
Stabilize integer logarithms Stabilizes feature `int_log`. I've also made the functions const stable, because they don't depend on any unstable const features. `rustc_allow_const_fn_unstable` is just there for `Option::expect`, which could be replaced with a `match` and `panic!`. cc ``@rust-lang/wg-const-eval`` closes rust-lang/rust#70887 (tracking issue) ~~blocked on FCP finishing: rust-lang/rust#70887 (comment) FCP finished: rust-lang/rust#70887 (comment)
Stabilize integer logarithms Stabilizes feature `int_log`. I've also made the functions const stable, because they don't depend on any unstable const features. `rustc_allow_const_fn_unstable` is just there for `Option::expect`, which could be replaced with a `match` and `panic!`. cc ``@rust-lang/wg-const-eval`` closes rust-lang/rust#70887 (tracking issue) ~~blocked on FCP finishing: rust-lang/rust#70887 (comment) FCP finished: rust-lang/rust#70887 (comment)
Stabilize integer logarithms Stabilizes feature `int_log`. I've also made the functions const stable, because they don't depend on any unstable const features. `rustc_allow_const_fn_unstable` is just there for `Option::expect`, which could be replaced with a `match` and `panic!`. cc ``@rust-lang/wg-const-eval`` closes rust-lang/rust#70887 (tracking issue) ~~blocked on FCP finishing: rust-lang/rust#70887 (comment) FCP finished: rust-lang/rust#70887 (comment)
Add `isqrt` to `NonZero<uN>` Implements [rust-lang#70887 (comment)](rust-lang#116226 (comment)), with the following signature: ```rust impl NonZero<uN> { const fn isqrt(self) -> Self; } ``` Unintended benefits include one fewer panicking branch in `ilog2` for LLVM to optimize away, and one fewer `assume_unchecked` as `NonZero` already does that. The fast path for `self == 1` is dropped, but the current implementation is very slow anyways compared to hardware. Performance improvements can always come later. (I didn't add the function to `NonZero<iN>`, since _every_ existing `NonZero` method is non-panicking, and it might be nice to leave it that way.)
Add `isqrt` to `NonZero<uN>` Implements [rust-lang#70887 (comment)](rust-lang#116226 (comment)), with the following signature: ```rust impl NonZero<uN> { const fn isqrt(self) -> Self; } ``` Unintended benefits include one fewer panicking branch in `ilog2` for LLVM to optimize away, and one fewer `assume_unchecked` as `NonZero` already does that. The fast path for `self == 1` is dropped, but the current implementation is very slow anyways compared to hardware. Performance improvements can always come later. (I didn't add the function to `NonZero<iN>`, since _every_ existing `NonZero` method is non-panicking, and it might be nice to leave it that way.)
Rollup merge of rust-lang#126199 - ivan-shrimp:nonzero_isqrt, r=tgross35 Add `isqrt` to `NonZero<uN>` Implements [rust-lang#70887 (comment)](rust-lang#116226 (comment)), with the following signature: ```rust impl NonZero<uN> { const fn isqrt(self) -> Self; } ``` Unintended benefits include one fewer panicking branch in `ilog2` for LLVM to optimize away, and one fewer `assume_unchecked` as `NonZero` already does that. The fast path for `self == 1` is dropped, but the current implementation is very slow anyways compared to hardware. Performance improvements can always come later. (I didn't add the function to `NonZero<iN>`, since _every_ existing `NonZero` method is non-panicking, and it might be nice to leave it that way.)
Feature gate:
#![feature(int_log)]
Stabilization report: #70887 (comment)
This is a tracking issue for adding
{checked_,}{ilog,ilog2,ilog10}
methods to{u8,u16,u32,u64,u128}
. A full rationale can be found in #80918 (comment). But in short: integer logarithms are fairly common, but require care to implement correctly, and effort to implement efficiently.Because we expose
log
methods for floats it can be tempting for users to use that instead, which can lead to rounding errors. In the following example we're trying to calculatebase10
for an integer. We might try and calculate thebase2
for the values, and attempt a base swap to arrive atbase10
. However because we're performing intermediate rounding we arrive at the wrong result:Public API
Steps / History
Unresolved Questions
ilog10
implementation? Add Integer::checked_{log,log2,log10} #70835 (comment)const fn
?NonZero{Int}
? Add Integer::checked_{log,log2,log10} #70835 (comment)Option
forilog2/ilog10
onNonZero{Int}
?Integer::{ilog,ilog2,ilog10}
instead? Add Integer::checked_{log,log2,log10} #70835 (comment) Tracking Issue for Integer::{ilog,ilog2,ilog10} #70887 (comment)Implementation History
log
methods, mergedlog2
andlog10
toNonZeroU*
#92956 -log
methods forNonZero
typeslog
methods toilog
{integer primitive}::ilog{,2,10}
in all modes #102578 - panic on invalid argsThe text was updated successfully, but these errors were encountered: