Description
First discussed in issue #10184.
As of Rust 1.39, 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.
PR #66841 adds that method to each of f32
and f64
.
/// Rounds toward zero and converts to any primitive integer type,
/// assuming that the value is finite and fits in that type.
///
/// ```
/// #![feature(float_approx_unchecked_to)]
///
/// let value = 4.6_f32;
/// let rounded = unsafe { value.approx_unchecked_to::<u16>() };
/// assert_eq!(rounded, 4);
///
/// let value = -128.9_f32;
/// let rounded = unsafe { value.approx_unchecked_to::<i8>() };
/// assert_eq!(rounded, std::i8::MIN);
/// ```
///
/// # Safety
///
/// The value must:
///
/// * Not be `NaN`
/// * Not be infinite
/// * Be representable in the return type `Int`, after truncating off its fractional part
#[cfg(not(bootstrap))]
#[unstable(feature = "float_approx_unchecked_to", issue = "0")]
#[inline]
pub unsafe fn approx_unchecked_to<Int>(self) -> Int where Self: FloatToInt<Int> {
FloatToInt::<Int>::approx_unchecked(self)
}
The FloatToInt
trait (tracking issue: #67057) has macro-generated impl
s for all combinations of primitive integer and primitive floating point types:
impl FloatToInt<$Int> for $Float {…}