Uh oh!
There was an error while loading. Please reload this page.
Add {f32,f64}::approx_unchecked_to<Int> unsafe methods - #66841
Conversation
rust-highfive
commented
Nov 28, 2019
r? @KodrAus (rust_highfive has picked a reviewer for you, use r? to override) |
SimonSapin
commented
Nov 28, 2019
Regarding naming: we already have These new methods differ from those in that they round towards zero. However they are already different enough in their return type that perhaps documentation is enough and this different rounding behavior doesn’t need to be called out in the method name? |
28486c3 to
296dc11CompareCentril
commented
Nov 28, 2019
r? @rkruppe |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Maybe this could be elaborated upon what finite and fitting entails?
There was a problem hiding this comment.
Finite is defined in the docs of the is_finite method, but I can repeat in this comment.
As discussed in the PR description, “fit” is copied from https://llvm.org/docs/LangRef.html#fptoui-to-instruction and I couldn’t find anything more precise. I’d prefer to find out what LLVM does exactly rather than documenting suppositions as fact, but I’m not sure how.
There was a problem hiding this comment.
Re. finite, maybe link to is_finite saying "as defined by is_finite"?
Hopefully @rkruppe is more knowledgeable re. "fit".
There was a problem hiding this comment.
This bit of doc-comment is now “The value must be finite (not infinite or NaN) and fit in the return type.” and I’ve added a (non-doc-) comment with a link to relevant LLVM docs.
There was a problem hiding this comment.
If it's not spelled out in LLVM's LangRef, then my working knowledge of how the instruction works probably isn't worth much. There's dozens of places in LLVM that could deviate from the expected semantics (various IR passes and utilities, as well as the lowerings in the backends) and I do not know all of them.
hanna-kruppe
commented
Nov 28, 2019
The implementation looks good to me. Regarding naming: I don't think "round" is a good name. Not only do we already have APIs that use "round" in a different sense for the same pairs of types (even if the signatures are not literally identical because these new functions are generic), I would also never think to suspect that something named just "round" defaults to RTZ mode, even with the context of a float -> int signature. I don't love any of these but here are some alternatives that seem less misleading to me:
|
SimonSapin
commented
Nov 28, 2019
Presumably C11 standard https://port70.net/~nsz/c/c11/n1570.html#6.3.1.4
C++17 standard http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf#section.7.10
So “fit” is indeed after rounding/truncation. |
SimonSapin
commented
Nov 28, 2019
@rkruppe What do you think of just |
hanna-kruppe
commented
Nov 28, 2019
Seems fine to me. I assume we don't really have to worry about a future name collision with a hypothetical |
SimonSapin
commented
Nov 28, 2019
I’m considering whether the trait should be something like |
SimonSapin
commented
Nov 29, 2019
These methods could fit among other conversion methods: https://internals.rust-lang.org/t/pre-rfc-add-explicitly-named-numeric-conversion-apis/11395 |
{f32,f64}::round_unchecked_to<Int> unsafe methods{f32,f64}::approx_unchecked_to<Int> unsafe methodsSimonSapin
commented
Dec 2, 2019
I’ve renamed the methods to |
427ec1b to
16a4fc3CompareSimonSapin
commented
Dec 5, 2019
hanna-kruppe
commented
Dec 5, 2019
I'm happy with the final diff but FWIW I also don't have any opinion on the API design aspects (e.g., the entirety of the The individual commits seem worth revising before merging, though:
|
As discussed in rust-lang#10184 Currently, casting a floating point number to an integer with `as` is Undefined Behavior if the value is out of range. `-Z saturating-float-casts` fixes this soundness hole by making `as` “saturate” to the maximum or minimum value of the integer type (or zero for `NaN`), but has measurable negative performance impact in some benchmarks. There is some consensus in that thread for enabling saturation by default anyway, but provide an `unsafe fn` alternative for users who know through some other mean that their values are in range.
This makes `libcore/num/mod.rs` slightly smaller. It’s still 4911 lines and not easy to navigate. This doesn’t change any public API.
37595ce to
a213ff8CompareSimonSapin
commented
Dec 6, 2019
Squashed. Input from @rust-lang/libs about the API design is welcome here. This is all |
hanna-kruppe
commented
Dec 6, 2019
Yes, let's merge this and bikeshedding can happen on the tracking issues. @bors r+ |
bors
commented
Dec 6, 2019
📌 Commit a213ff8 has been approved by |
…, r=rkruppe
Add `{f32,f64}::approx_unchecked_to<Int>` unsafe methods
As discussed in rust-lang#10184
Currently, casting a floating point number to an integer with `as` is Undefined Behavior if the value is out of range. `-Z saturating-float-casts` fixes this soundness hole by making `as` “saturate” to the maximum or minimum value of the integer type (or zero for `NaN`), but has measurable negative performance impact in some benchmarks. There is some consensus in that thread for enabling saturation by default anyway, but provide an `unsafe fn` alternative for users who know through some other mean that their values are in range.
<del>The “fit” wording is copied from https://llvm.org/docs/LangRef.html#fptoui-to-instruction, but I’m not certain what it means exactly. Presumably this is after rounding towards zero, and the doc-test with `i8::MIN` seems to confirm this.</del> Clang presumably uses those LLVM intrinsics to implement C and C++ casts, whose respective standard specify that the value *after truncating to keep its integral part* must be representable in the target type.Rollup of 10 pull requests Successful merges: - #66606 (Add feature gate for mut refs in const fn) - #66841 (Add `{f32,f64}::approx_unchecked_to<Int>` unsafe methods) - #67009 (Emit coercion suggestions in more places) - #67052 (Ditch `parse_in_attr`) - #67071 (Do not ICE on closure typeck) - #67078 (accept union inside enum if not followed by identifier) - #67090 (Change "either" to "any" in Layout::from_size_align's docs) - #67092 (Fix comment typos in src/libcore/alloc.rs) - #67094 (get rid of __ in field names) - #67102 (Add note to src/ci/docker/README.md about multiple docker images) Failed merges: - #67101 (use `#[allow(unused_attributes)]` to paper over incr.comp problem) r? @ghost
As discussed in #10184
Currently, casting a floating point number to an integer with
asis Undefined Behavior if the value is out of range.-Z saturating-float-castsfixes this soundness hole by makingas“saturate” to the maximum or minimum value of the integer type (or zero forNaN), but has measurable negative performance impact in some benchmarks. There is some consensus in that thread for enabling saturation by default anyway, but provide anunsafe fnalternative for users who know through some other mean that their values are in range.The “fit” wording is copied from https://llvm.org/docs/LangRef.html#fptoui-to-instruction, but I’m not certain what it means exactly. Presumably this is after rounding towards zero, and the doc-test withClang presumably uses those LLVM intrinsics to implement C and C++ casts, whose respective standard specify that the value after truncating to keep its integral part must be representable in the target type.i8::MINseems to confirm this.