duration div mul extras
This commit is contained in:
parent
c7cba3d33f
commit
c24fb126e7
2 changed files with 141 additions and 0 deletions
|
|
@ -24,6 +24,7 @@
|
|||
use fmt;
|
||||
use iter::Sum;
|
||||
use ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
|
||||
use {u64, u128};
|
||||
|
||||
const NANOS_PER_SEC: u32 = 1_000_000_000;
|
||||
const NANOS_PER_MILLI: u32 = 1_000_000;
|
||||
|
|
@ -501,6 +502,67 @@ impl Mul<u32> for Duration {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "duration_mul_div_extras", since = "1.29.0")]
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "duration_mul_div_extras", since = "1.29.0")]
|
||||
impl Mul<f64> for Duration {
|
||||
type Output = Duration;
|
||||
|
||||
fn mul(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");
|
||||
}
|
||||
if nanos_f64 > (u128::MAX as f64) {
|
||||
panic!("overflow when multiplying duration by float");
|
||||
};
|
||||
let nanos_u128 = nanos_f64 as u128;
|
||||
let secs = nanos_u128 / (NANOS_PER_SEC as u128);
|
||||
let nanos = nanos_u128 % (NANOS_PER_SEC as u128);
|
||||
if secs > (u64::MAX as u128) {
|
||||
panic!("overflow when multiplying duration by float");
|
||||
}
|
||||
Duration {
|
||||
secs: secs as u64,
|
||||
nanos: nanos as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "duration_mul_div_extras", since = "1.29.0")]
|
||||
impl Mul<Duration> for f64 {
|
||||
type Output = Duration;
|
||||
|
||||
fn mul(self, rhs: Duration) -> Duration {
|
||||
const NPS: f64 = NANOS_PER_SEC as f64;
|
||||
let nanos_f64 = self * (NPS * (rhs.secs as f64) + (rhs.nanos as f64));
|
||||
if !nanos_f64.is_finite() {
|
||||
panic!("got non-finite value when multiplying float by duration");
|
||||
}
|
||||
if nanos_f64 > (u128::MAX as f64) {
|
||||
panic!("overflow when multiplying float by duration");
|
||||
};
|
||||
let nanos_u128 = nanos_f64 as u128;
|
||||
let secs = nanos_u128 / (NANOS_PER_SEC as u128);
|
||||
let nanos = nanos_u128 % (NANOS_PER_SEC as u128);
|
||||
if secs > (u64::MAX as u128) {
|
||||
panic!("overflow when multiplying float by duration");
|
||||
}
|
||||
Duration {
|
||||
secs: secs as u64,
|
||||
nanos: nanos as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
|
||||
impl MulAssign<u32> for Duration {
|
||||
fn mul_assign(&mut self, rhs: u32) {
|
||||
|
|
@ -508,6 +570,13 @@ impl MulAssign<u32> for Duration {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "duration_mul_div_extras", since = "1.29.0")]
|
||||
impl MulAssign<f64> for Duration {
|
||||
fn mul_assign(&mut self, rhs: f64) {
|
||||
*self = *self * rhs;
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "duration", since = "1.3.0")]
|
||||
impl Div<u32> for Duration {
|
||||
type Output = Duration;
|
||||
|
|
@ -517,6 +586,44 @@ impl Div<u32> for Duration {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "duration_mul_div_extras", since = "1.29.0")]
|
||||
impl Div<f64> for Duration {
|
||||
type Output = Duration;
|
||||
|
||||
fn div(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 > (u128::MAX as f64) {
|
||||
panic!("overflow when dividing duration by float");
|
||||
};
|
||||
let nanos_u128 = nanos_f64 as u128;
|
||||
let secs = nanos_u128 / (NANOS_PER_SEC as u128);
|
||||
let nanos = nanos_u128 % (NANOS_PER_SEC as u128);
|
||||
if secs > (u64::MAX as u128) {
|
||||
panic!("overflow when dividing duration by float");
|
||||
}
|
||||
Duration {
|
||||
secs: secs as u64,
|
||||
nanos: nanos as u32,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "duration_mul_div_extras", since = "1.29.0")]
|
||||
impl Div<Duration> for Duration {
|
||||
type Output = f64;
|
||||
|
||||
fn div(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
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "time_augmented_assignment", since = "1.9.0")]
|
||||
impl DivAssign<u32> for Duration {
|
||||
fn div_assign(&mut self, rhs: u32) {
|
||||
|
|
@ -524,6 +631,14 @@ impl DivAssign<u32> for Duration {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "duration_mul_div_extras", since = "1.29.0")]
|
||||
impl DivAssign<f64> for Duration {
|
||||
fn div_assign(&mut self, rhs: f64) {
|
||||
*self = *self / rhs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
macro_rules! sum_durations {
|
||||
($iter:expr) => {{
|
||||
let mut total_secs: u64 = 0;
|
||||
|
|
|
|||
|
|
@ -590,4 +590,30 @@ mod tests {
|
|||
let hundred_twenty_years = thirty_years * 4;
|
||||
assert!(a < hundred_twenty_years);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn duration_float_ops() {
|
||||
let dur = Duration::new(2, 700_000_000);
|
||||
|
||||
let dur2 = 3.14*dur;
|
||||
assert_eq!(dur2, dur*3.14);
|
||||
assert_eq!(dur2.as_secs(), 8);
|
||||
assert_eq!(dur2.subsec_nanos(), 478_000_000);
|
||||
|
||||
let dur3 = 3.14e5*dur;
|
||||
assert_eq!(dur3, dur*3.14e5);
|
||||
assert_eq!(dur3.as_secs(), 847_800);
|
||||
assert_eq!(dur3.subsec_nanos(), 0);
|
||||
|
||||
let dur4 = dur/3.14;
|
||||
assert_eq!(dur4.as_secs(), 0);
|
||||
assert_eq!(dur4.subsec_nanos(), 859_872_611);
|
||||
|
||||
let dur5 = dur/3.14e5;
|
||||
assert_eq!(dur5.as_secs(), 0);
|
||||
// we are using truncation and not rounding
|
||||
assert_eq!(dur5.subsec_nanos(), 8598);
|
||||
|
||||
assert_eq!(dur/Duration::new(5, 400_000_000), 0.5);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue