const NANOS_PER_MICRO: u32 = 1_000;
const MILLIS_PER_SEC: u64 = 1_000;
const MICROS_PER_SEC: u64 = 1_000_000;
-const MAX_NANOS_F64: f64 = ((u64::MAX as u128)*(NANOS_PER_SEC as u128)) as f64;
+const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128) - 1) as f64;
/// A `Duration` type to represent a span of time, typically used for system
/// timeouts.
}
}
- /// Multiply `Duration` by `f64`.
+ /// Returns the number of seconds contained by this `Duration` as `f64`.
+ ///
+ /// The returned value does include the fractional (nanosecond) part of the duration.
///
/// # Examples
/// ```
+ /// #![feature(duration_float)]
/// 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));
+ /// assert_eq!(dur.as_float_secs(), 2.7);
/// ```
- #[unstable(feature = "duration_float_ops",
- reason = "duration/floats operations are unstabe",
- issue = "0")]
+ #[unstable(feature = "duration_float", issue = "0")]
#[inline]
- pub fn mul_f64(self, rhs: f64) -> Duration {
- const NPS: f64 = NANOS_PER_SEC as f64;
- let nanos_f64 = rhs * (NPS * (self.secs as f64) + (self.nanos as f64));
- if !nanos_f64.is_finite() {
- panic!("got non-finite value when multiplying duration by float");
+ pub fn as_float_secs(&self) -> f64 {
+ (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64)
+ }
+
+ /// Creates a new `Duration` from the specified number of seconds.
+ ///
+ /// # Examples
+ /// ```
+ /// #![feature(duration_float)]
+ /// use std::time::Duration;
+ ///
+ /// let dur = Duration::from_float_secs(2.7);
+ /// assert_eq!(dur, Duration::new(2, 700_000_000));
+ /// ```
+ #[unstable(feature = "duration_float", issue = "0")]
+ #[inline]
+ pub fn from_float_secs(secs: f64) -> Duration {
+ let nanos = secs * (NANOS_PER_SEC as f64);
+ if !nanos.is_finite() {
+ panic!("got non-finite value when converting float to duration");
}
- if nanos_f64 > MAX_NANOS_F64 {
- panic!("overflow when multiplying duration by float");
+ if nanos > MAX_NANOS_F64 {
+ panic!("overflow when converting float to duration");
}
- if nanos_f64 < 0.0 {
- panic!("underflow when multiplying duration by float");
+ if nanos < 0.0 {
+ panic!("underflow when converting float to duration");
}
- let nanos_u128 = nanos_f64 as u128;
+ let nanos = nanos as u128;
Duration {
- secs: (nanos_u128 / (NANOS_PER_SEC as u128)) as u64,
- nanos: (nanos_u128 % (NANOS_PER_SEC as u128)) as u32,
+ secs: (nanos / (NANOS_PER_SEC as u128)) as u64,
+ nanos: (nanos % (NANOS_PER_SEC as u128)) as u32,
}
}
+ /// Multiply `Duration` by `f64`.
+ ///
+ /// # Examples
+ /// ```
+ /// #![feature(duration_float)]
+ /// 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));
+ /// ```
+ #[unstable(feature = "duration_float", issue = "0")]
+ #[inline]
+ pub fn mul_f64(self, rhs: f64) -> Duration {
+ Duration::from_float_secs(rhs * self.as_float_secs())
+ }
+
/// Divide `Duration` by `f64`.
///
/// # Examples
/// ```
+ /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur = Duration::new(2, 700_000_000);
/// // note that truncation is used, not rounding
/// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
/// ```
- #[unstable(feature = "duration_float_ops",
- reason = "duration/floats operations are unstabe",
- issue = "0")]
+ #[unstable(feature = "duration_float", issue = "0")]
#[inline]
pub fn div_f64(self, rhs: f64) -> Duration {
- const NPS: f64 = NANOS_PER_SEC as f64;
- let nanos_f64 = (NPS * (self.secs as f64) + (self.nanos as f64)) / rhs;
- if !nanos_f64.is_finite() {
- panic!("got non-finite value when dividing duration by float");
- }
- if nanos_f64 > MAX_NANOS_F64 {
- panic!("overflow when dividing duration by float");
- }
- if nanos_f64 < 0.0 {
- panic!("underflow when multiplying duration by float");
- }
- let nanos_u128 = nanos_f64 as u128;
- Duration {
- secs: (nanos_u128 / (NANOS_PER_SEC as u128)) as u64,
- nanos: (nanos_u128 % (NANOS_PER_SEC as u128)) as u32,
- }
+ Duration::from_float_secs(self.as_float_secs() / rhs)
}
/// Divide `Duration` by `Duration` and return `f64`.
///
/// # Examples
/// ```
+ /// #![feature(duration_float)]
/// use std::time::Duration;
///
/// let dur1 = Duration::new(2, 700_000_000);
/// let dur2 = Duration::new(5, 400_000_000);
/// assert_eq!(dur1.div_duration(dur2), 0.5);
/// ```
- #[unstable(feature = "duration_float_ops",
- reason = "duration/floats operations are unstabe",
- issue = "0")]
+ #[unstable(feature = "duration_float", issue = "0")]
#[inline]
pub fn div_duration(self, rhs: Duration) -> f64 {
- const NPS: f64 = NANOS_PER_SEC as f64;
- let nanos1 = NPS * (self.secs as f64) + (self.nanos as f64);
- let nanos2 = NPS * (rhs.secs as f64) + (rhs.nanos as f64);
- nanos1/nanos2
+ self.as_float_secs() / rhs.as_float_secs()
}
}
type Output = Duration;
fn mul(self, rhs: Duration) -> Duration {
- rhs.checked_mul(self).expect("overflow when multiplying scalar by duration")
+ rhs * self
}
}