@@ -275,6 +275,70 @@ impl f128 {
275275 #[ unstable( feature = "f128" , issue = "116909" ) ]
276276 pub const NEG_INFINITY : f128 = -1.0_f128 / 0.0_f128 ;
277277
278+ /// Maximum integer that can be represented exactly in an [`f128`] value,
279+ /// with no other integer converting to the same floating point value.
280+ ///
281+ /// For an integer `x` which satisfies `MIN_EXACT_INTEGER <= x <= MAX_EXACT_INTEGER`,
282+ /// there is a "one-to-one" mapping between [`i128`] and [`f128`] values.
283+ /// `MAX_EXACT_INTEGER + 1` also converts losslessly to [`f128`] and back to
284+ /// [`i128`], but `MAX_EXACT_INTEGER + 2` converts to the same [`f128`] value
285+ /// (and back to `MAX_EXACT_INTEGER + 1` as an integer) so there is not a
286+ /// "one-to-one" mapping.
287+ ///
288+ /// [`MAX_EXACT_INTEGER`]: f128::MAX_EXACT_INTEGER
289+ /// [`MIN_EXACT_INTEGER`]: f128::MIN_EXACT_INTEGER
290+ /// ```
291+ /// #![feature(f128)]
292+ /// #![feature(float_exact_integer_constants)]
293+ /// # // FIXME(#152635): Float rounding on `i586` does not adhere to IEEE 754
294+ /// # #[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))] {
295+ /// # #[cfg(target_has_reliable_f128)] {
296+ /// let max_exact_int = f128::MAX_EXACT_INTEGER;
297+ /// assert_eq!(max_exact_int, max_exact_int as f128 as i128);
298+ /// assert_eq!(max_exact_int + 1, (max_exact_int + 1) as f128 as i128);
299+ /// assert_ne!(max_exact_int + 2, (max_exact_int + 2) as f128 as i128);
300+ ///
301+ /// // Beyond `f128::MAX_EXACT_INTEGER`, multiple integers can map to one float value
302+ /// assert_eq!((max_exact_int + 1) as f128, (max_exact_int + 2) as f128);
303+ /// # }}
304+ /// ```
305+ // #[unstable(feature = "f128", issue = "116909")]
306+ #[ unstable( feature = "float_exact_integer_constants" , issue = "152466" ) ]
307+ pub const MAX_EXACT_INTEGER : i128 = ( 1 << Self :: MANTISSA_DIGITS ) - 1 ;
308+
309+ /// Minimum integer that can be represented exactly in an [`f128`] value,
310+ /// with no other integer converting to the same floating point value.
311+ ///
312+ /// For an integer `x` which satisfies `MIN_EXACT_INTEGER <= x <= MAX_EXACT_INTEGER`,
313+ /// there is a "one-to-one" mapping between [`i128`] and [`f128`] values.
314+ /// `MAX_EXACT_INTEGER + 1` also converts losslessly to [`f128`] and back to
315+ /// [`i128`], but `MAX_EXACT_INTEGER + 2` converts to the same [`f128`] value
316+ /// (and back to `MAX_EXACT_INTEGER + 1` as an integer) so there is not a
317+ /// "one-to-one" mapping.
318+ ///
319+ /// This constant is equivalent to `-MAX_EXACT_INTEGER`.
320+ ///
321+ /// [`MAX_EXACT_INTEGER`]: f128::MAX_EXACT_INTEGER
322+ /// [`MIN_EXACT_INTEGER`]: f128::MIN_EXACT_INTEGER
323+ /// ```
324+ /// #![feature(f128)]
325+ /// #![feature(float_exact_integer_constants)]
326+ /// # // FIXME(#152635): Float rounding on `i586` does not adhere to IEEE 754
327+ /// # #[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))] {
328+ /// # #[cfg(target_has_reliable_f128)] {
329+ /// let min_exact_int = f128::MIN_EXACT_INTEGER;
330+ /// assert_eq!(min_exact_int, min_exact_int as f128 as i128);
331+ /// assert_eq!(min_exact_int - 1, (min_exact_int - 1) as f128 as i128);
332+ /// assert_ne!(min_exact_int - 2, (min_exact_int - 2) as f128 as i128);
333+ ///
334+ /// // Below `f128::MIN_EXACT_INTEGER`, multiple integers can map to one float value
335+ /// assert_eq!((min_exact_int - 1) as f128, (min_exact_int - 2) as f128);
336+ /// # }}
337+ /// ```
338+ // #[unstable(feature = "f128", issue = "116909")]
339+ #[ unstable( feature = "float_exact_integer_constants" , issue = "152466" ) ]
340+ pub const MIN_EXACT_INTEGER : i128 = -Self :: MAX_EXACT_INTEGER ;
341+
278342 /// Sign bit
279343 pub ( crate ) const SIGN_MASK : u128 = 0x8000_0000_0000_0000_0000_0000_0000_0000 ;
280344
0 commit comments