Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 82 additions & 6 deletions library/core/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1006,13 +1006,45 @@ impl Duration {
/// This method will panic if result is negative, overflows `Duration` or not finite.
///
/// # Examples
///
/// ```
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// assert_eq!(dur.mul_f64(3.14), Duration::new(8, 478_000_000));
/// assert_eq!(dur.mul_f64(3.14e5), Duration::new(847_800, 0));
/// ```
///
/// Note that `f64` does not have enough bits ([`f64::MANTISSA_DIGITS`]) to represent the full
/// range of possible `Duration` with nanosecond precision, so rounding may occur even for
/// trivial operations like multiplying by 1.
///
/// ```
/// # #![feature(float_exact_integer_constants)]
/// use std::time::Duration;
///
/// // This is about 14.9 weeks, remaining precise to the nanosecond:
/// let weeks = Duration::from_nanos(f64::MAX_EXACT_INTEGER as u64);
/// assert_eq!(weeks, weeks.mul_f64(1.0));
///
/// // A larger value incurs rounding in the floating-point operation:
/// let weeks = Duration::from_nanos(u64::MAX);
/// assert_ne!(weeks, weeks.mul_f64(1.0));
///
/// // This is over 285 million years, remaining precise to the second:
/// let years = Duration::from_secs(f64::MAX_EXACT_INTEGER as u64);
/// assert_eq!(years, years.mul_f64(1.0));
///
/// // And again larger values incur rounding:
/// let years = Duration::from_secs(u64::MAX / 2);
/// assert_ne!(years, years.mul_f64(1.0));
/// ```
///
/// ```should_panic
/// # use std::time::Duration;
/// // In the extreme, rounding can even overflow `Duration`, which panics.
/// let _ = Duration::from_secs(u64::MAX).mul_f64(1.0);
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand All @@ -1023,6 +1055,10 @@ impl Duration {

/// Multiplies `Duration` by `f32`.
///
/// Since the significand of `f32` is quite limited compared to the range of `Duration`
/// -- only about 16.8ms of exact nanosecond precision -- this method currently forwards
/// to [`mul_f64`][Self::mul_f64] for greater accuracy.
///
/// # Panics
/// This method will panic if result is negative, overflows `Duration` or not finite.
///
Expand All @@ -1031,15 +1067,18 @@ impl Duration {
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_641));
/// // Note that this `3.14_f32` argument already has more floating-point
/// // representation error than a direct `3.14_f64` would, so the result
/// // is slightly different from the ideal 8.478s.
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_283));
/// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0));
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn mul_f32(self, rhs: f32) -> Duration {
Duration::from_secs_f32(rhs * self.as_secs_f32())
self.mul_f64(rhs.into())
}

/// Divides `Duration` by `f64`.
Expand All @@ -1048,13 +1087,45 @@ impl Duration {
/// This method will panic if result is negative, overflows `Duration` or not finite.
///
/// # Examples
///
/// ```
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// assert_eq!(dur.div_f64(3.14), Duration::new(0, 859_872_611));
/// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_599));
/// ```
///
/// Note that `f64` does not have enough bits ([`f64::MANTISSA_DIGITS`]) to represent the full
/// range of possible `Duration` with nanosecond precision, so rounding may occur even for
/// trivial operations like dividing by 1.
///
/// ```
/// # #![feature(float_exact_integer_constants)]
/// use std::time::Duration;
///
/// // This is about 14.9 weeks, remaining precise to the nanosecond:
/// let weeks = Duration::from_nanos(f64::MAX_EXACT_INTEGER as u64);
/// assert_eq!(weeks, weeks.div_f64(1.0));
///
/// // A larger value incurs rounding in the floating-point operation:
/// let weeks = Duration::from_nanos(u64::MAX);
/// assert_ne!(weeks, weeks.div_f64(1.0));
///
/// // This is over 285 million years, remaining precise to the second:
/// let years = Duration::from_secs(f64::MAX_EXACT_INTEGER as u64);
/// assert_eq!(years, years.div_f64(1.0));
///
/// // And again larger values incur rounding:
/// let years = Duration::from_secs(u64::MAX / 2);
/// assert_ne!(years, years.div_f64(1.0));
/// ```
///
/// ```should_panic
/// # use std::time::Duration;
/// // In the extreme, rounding can even overflow `Duration`, which panics.
/// let _ = Duration::from_secs(u64::MAX).div_f64(1.0);
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
Expand All @@ -1065,6 +1136,10 @@ impl Duration {

/// Divides `Duration` by `f32`.
///
/// Since the significand of `f32` is quite limited compared to the range of `Duration`
/// -- only about 16.8ms of exact nanosecond precision -- this method currently forwards
/// to [`div_f64`][Self::div_f64] for greater accuracy.
///
/// # Panics
/// This method will panic if result is negative, overflows `Duration` or not finite.
///
Expand All @@ -1073,17 +1148,18 @@ impl Duration {
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// // note that due to rounding errors result is slightly
/// // different from 0.859_872_611
/// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_580));
/// // Note that this `3.14_f32` argument already has more floating-point
/// // representation error than a direct `3.14_f64` would, so the result
/// // is slightly different from the ideally rounded 0.859_872_611.
/// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_583));
/// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_599));
/// ```
#[stable(feature = "duration_float", since = "1.38.0")]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
pub fn div_f32(self, rhs: f32) -> Duration {
Duration::from_secs_f32(self.as_secs_f32() / rhs)
self.div_f64(rhs.into())
}

/// Divides `Duration` by `Duration` and returns `f64`.
Expand Down
Loading