-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Duration div mul extras #52813
Duration div mul extras #52813
Changes from 1 commit
c24fb12
12d8f27
3e07236
2c300fa
2cab0de
d48a649
0673417
36dff2a
206ca68
07c15ea
c5cbea6
533c0f0
c11281f
37972ae
8a0aa9f
9e78cb2
2aca697
fd7565b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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,13 +502,81 @@ 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)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider panicking when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. |
||
if !nanos_f64.is_finite() { | ||
panic!("got non-finite value when multiplying duration by float"); | ||
} | ||
if nanos_f64 > (u128::MAX as f64) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The upper limit is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was conservative about potential edge effects. So you think it will be enough to just check the following condition? nanos_f64 > ((u64::MAX as u128)*(NANOS_PER_SEC as u128)) as f64 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @newpavlov Yes. But make this a |
||
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) { | ||
*self = *self * rhs; | ||
} | ||
} | ||
|
||
#[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,13 +586,59 @@ 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) { | ||
*self = *self / rhs; | ||
} | ||
} | ||
|
||
#[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; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just use
rhs * self
to avoid repeating things?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They have different panic messages "multiplying scalar by duration" vs "multiplying duration by scalar"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If having different panic messages is not important, then I'll change it and
f64
impl torhs * self
.