]> git.lizzy.rs Git - rust.git/blobdiff - src/libcore/time.rs
move checks to from_float_secs
[rust.git] / src / libcore / time.rs
index 294c999269740c3f1d910c145900bbe6bb74858f..f0e4b29700b4651b50e48eb29d3ff38c86e1c2a8 100644 (file)
@@ -30,7 +30,7 @@
 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.
@@ -460,43 +460,76 @@ pub fn checked_div(self, rhs: u32) -> Option<Duration> {
         }
     }
 
-    /// 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);
@@ -504,48 +537,27 @@ pub fn mul_f64(self, rhs: f64) -> Duration {
     /// // 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()
     }
 }
 
@@ -595,7 +607,7 @@ impl Mul<Duration> for u32 {
     type Output = Duration;
 
     fn mul(self, rhs: Duration) -> Duration {
-        rhs.checked_mul(self).expect("overflow when multiplying scalar by duration")
+        rhs * self
     }
 }