-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Implement total_cmp for f32, f64 #72568
Conversation
(rust_highfive has picked a reviewer for you, use r? to override) |
Just a note: I'm not entirely sure, but I realized that we might have some architectures (old MIPS chips?) in Tier 2 support that do not exactly conform to the 2008 revision, although they |
r? @sfackler |
What change was made in 754-2019 specifically? |
Co-authored-by: bluss <bluss@users.noreply.github.com>
Co-authored-by: bluss <bluss@users.noreply.github.com>
@sfackler The way the order phrased in 2008 revision is as follows: I don't currently have access to the text of 2019 revision, but according to these "background documents" http://grouper.ieee.org/groups/msc/ANSI_IEEE-Std-754-2019/background/ it seems that the requirement "lesser payload, when regarded as an integer, orders below greater payload for +NaN, reverse for -NaN." was removed:
Reading that again, that might or might not still mean that ordering between qNaN and sNan is required by 2019. I don't know. If somebody has access to the text, please enlighten me. |
/// ``` | ||
#[unstable(feature = "total_cmp", issue = "none")] | ||
#[inline] | ||
pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this implementation sourced from somewhere else? Might be nice to link to that for easy reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is from scratch but the idea was adapted from an earlier thread here: rust-lang/rfcs#1249 (comment)
7bd87ff
to
8bc31ff
Compare
Oops, sorry. I touched an unrelated submodule accidentally. I don't want to mess other state up, so rebased and force-pushed. |
Can you make a tracking issue and reference it in the stability annotations? LGTM otherwise; thanks for the extensive tests! |
@sfackler Done! |
@bors r+ Thanks! |
📌 Commit 66da735 has been approved by |
… r=sfackler Implement total_cmp for f32, f64 # Overview * Implements method `total_cmp` on `f32` and `f64`. This method implements a float comparison that, unlike the standard `partial_cmp`, is total (defined on all values) in accordance to the IEEE 754 (rev 2008) §5.10 `totalOrder` predicate. * The method has an API similar to `cmp`: `pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering { ... }`. * Implements tests. * Has documentation. # Justification for the API * Total ordering for `f32` and `f64` has been discussed many time before: * https://internals.rust-lang.org/t/pre-pre-rfc-range-restricting-wrappers-for-floating-point-types/6701 * rust-lang/rfcs#1249 * rust-lang#53938 * rust-lang#5585 * The lack of total ordering leads to frequent complaints, especially from people new to Rust. * This is an ergonomics issue that needs to be addressed. * However, the default behaviour of implementing only `PartialOrd` is intentional, as relaxing it might lead to correctness issues. * Most earlier implementations and discussions have been focusing on a wrapper type that implements trait `Ord`. Such a wrapper type is, however not easy to add because of the large API surface added. * As a minimal step that hopefully proves uncontroversial, we can implement a stand-alone method `total_cmp` on floating point types. * I expect adding such methods should be uncontroversial because... * Similar methods on `f32` and `f64` would be warranted even in case stdlib would provide a wrapper type that implements `Ord` some day. * It implements functionality that is standardised. (IEEE 754, 2008 rev. §5.10 Note, that the 2019 revision relaxes the ordering. The way we do ordering in this method conforms to the stricter 2008 standard.) * With stdlib APIs such as `slice::sort_by` and `slice::binary_search_by` that allow users to provide a custom ordering criterion, providing additional helper methods is a minimal way of adding ordering functionality. * Not also does it allow easily using aforementioned APIs, it also provides an easy and well-tested primitive for the users and library authors to implement an `Ord`-implementing wrapper, if needed.
… r=sfackler Implement total_cmp for f32, f64 # Overview * Implements method `total_cmp` on `f32` and `f64`. This method implements a float comparison that, unlike the standard `partial_cmp`, is total (defined on all values) in accordance to the IEEE 754 (rev 2008) §5.10 `totalOrder` predicate. * The method has an API similar to `cmp`: `pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering { ... }`. * Implements tests. * Has documentation. # Justification for the API * Total ordering for `f32` and `f64` has been discussed many time before: * https://internals.rust-lang.org/t/pre-pre-rfc-range-restricting-wrappers-for-floating-point-types/6701 * rust-lang/rfcs#1249 * rust-lang#53938 * rust-lang#5585 * The lack of total ordering leads to frequent complaints, especially from people new to Rust. * This is an ergonomics issue that needs to be addressed. * However, the default behaviour of implementing only `PartialOrd` is intentional, as relaxing it might lead to correctness issues. * Most earlier implementations and discussions have been focusing on a wrapper type that implements trait `Ord`. Such a wrapper type is, however not easy to add because of the large API surface added. * As a minimal step that hopefully proves uncontroversial, we can implement a stand-alone method `total_cmp` on floating point types. * I expect adding such methods should be uncontroversial because... * Similar methods on `f32` and `f64` would be warranted even in case stdlib would provide a wrapper type that implements `Ord` some day. * It implements functionality that is standardised. (IEEE 754, 2008 rev. §5.10 Note, that the 2019 revision relaxes the ordering. The way we do ordering in this method conforms to the stricter 2008 standard.) * With stdlib APIs such as `slice::sort_by` and `slice::binary_search_by` that allow users to provide a custom ordering criterion, providing additional helper methods is a minimal way of adding ordering functionality. * Not also does it allow easily using aforementioned APIs, it also provides an easy and well-tested primitive for the users and library authors to implement an `Ord`-implementing wrapper, if needed.
… r=sfackler Implement total_cmp for f32, f64 # Overview * Implements method `total_cmp` on `f32` and `f64`. This method implements a float comparison that, unlike the standard `partial_cmp`, is total (defined on all values) in accordance to the IEEE 754 (rev 2008) §5.10 `totalOrder` predicate. * The method has an API similar to `cmp`: `pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering { ... }`. * Implements tests. * Has documentation. # Justification for the API * Total ordering for `f32` and `f64` has been discussed many time before: * https://internals.rust-lang.org/t/pre-pre-rfc-range-restricting-wrappers-for-floating-point-types/6701 * rust-lang/rfcs#1249 * rust-lang#53938 * rust-lang#5585 * The lack of total ordering leads to frequent complaints, especially from people new to Rust. * This is an ergonomics issue that needs to be addressed. * However, the default behaviour of implementing only `PartialOrd` is intentional, as relaxing it might lead to correctness issues. * Most earlier implementations and discussions have been focusing on a wrapper type that implements trait `Ord`. Such a wrapper type is, however not easy to add because of the large API surface added. * As a minimal step that hopefully proves uncontroversial, we can implement a stand-alone method `total_cmp` on floating point types. * I expect adding such methods should be uncontroversial because... * Similar methods on `f32` and `f64` would be warranted even in case stdlib would provide a wrapper type that implements `Ord` some day. * It implements functionality that is standardised. (IEEE 754, 2008 rev. §5.10 Note, that the 2019 revision relaxes the ordering. The way we do ordering in this method conforms to the stricter 2008 standard.) * With stdlib APIs such as `slice::sort_by` and `slice::binary_search_by` that allow users to provide a custom ordering criterion, providing additional helper methods is a minimal way of adding ordering functionality. * Not also does it allow easily using aforementioned APIs, it also provides an easy and well-tested primitive for the users and library authors to implement an `Ord`-implementing wrapper, if needed.
Rollup of 9 pull requests Successful merges: - rust-lang#72310 (Add Peekable::next_if) - rust-lang#72383 (Suggest using std::mem::drop function instead of explicit destructor call) - rust-lang#72398 (SocketAddr and friends now correctly pad its content) - rust-lang#72465 (Warn about unused captured variables) - rust-lang#72568 (Implement total_cmp for f32, f64) - rust-lang#72572 (Add some regression tests) - rust-lang#72591 (librustc_middle: Rename upvar_list to closure_captures) - rust-lang#72701 (Fix grammar in liballoc raw_vec) - rust-lang#72731 (Add missing empty line in E0619 explanation) Failed merges: r? @ghost
…r=Mark-Simulacrum Run standard library unit tests without optimizations in `nopt` CI jobs This was discussed in rust-lang#73288 as a way to catch similar issues in the future. This builds an unoptimized standard library with the bootstrap compiler and runs the unit tests. This takes about 2 minutes on my laptop. I confirmed that this method works locally, although there may be a better way of implementing it. It would be better to use the stage 2 compiler instead of the bootstrap one. Notably, there are currently four `libstd` unit tests that fail in debug mode on `i686-unkown-linux-gnu` (a tier one target): ``` failures: f32::tests::test_float_bits_conv f32::tests::test_total_cmp f64::tests::test_float_bits_conv f64::tests::test_total_cmp ``` These are the tests that prompted rust-lang#73288 as well as the ones added in rust-lang#72568, which is currently broken due to rust-lang#73328.
Overview
total_cmp
onf32
andf64
. This method implements a float comparison that, unlike the standardpartial_cmp
, is total (defined on all values) in accordance to the IEEE 754 (rev 2008) §5.10totalOrder
predicate.cmp
:pub fn total_cmp(&self, other: &Self) -> crate::cmp::Ordering { ... }
.Justification for the API
f32
andf64
has been discussed many time before:PartialOrd
is intentional, as relaxing it might lead to correctness issues.Ord
. Such a wrapper type is, however not easy to add because of the large API surface added.total_cmp
on floating point types.f32
andf64
would be warranted even in case stdlib would provide a wrapper type that implementsOrd
some day.slice::sort_by
andslice::binary_search_by
that allow users to provide a custom ordering criterion, providing additional helper methods is a minimal way of adding ordering functionality.Ord
-implementing wrapper, if needed.