Skip to content

Commit

Permalink
Port Duration::from_secs_f32|64 from std
Browse files Browse the repository at this point in the history
This ports the algorithm for constructing `Duration` from floating point
seconds from `std`. The new algorithm in `std` uses bit manipulation to
construct the `Duration` with the most precision possible. Additionally
this adds `saturating` and `checked` variants of those functions.

Original `std` PR: rust-lang/rust#90247

Co-authored-by: Ted Wollman <[email protected]>
  • Loading branch information
2 people authored and jhpratt committed May 10, 2023
1 parent 22ae579 commit e83d01f
Show file tree
Hide file tree
Showing 3 changed files with 360 additions and 22 deletions.
20 changes: 20 additions & 0 deletions benchmarks/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,26 @@ setup_benchmark! {
ben.iter(|| Duration::seconds_f32(-0.5));
}

fn saturating_seconds_f64(ben: &mut Bencher<'_>) {
ben.iter(|| Duration::saturating_seconds_f64(0.5));
ben.iter(|| Duration::saturating_seconds_f64(-0.5));
}

fn saturating_seconds_f32(ben: &mut Bencher<'_>) {
ben.iter(|| Duration::saturating_seconds_f32(0.5));
ben.iter(|| Duration::saturating_seconds_f32(-0.5));
}

fn checked_seconds_f64(ben: &mut Bencher<'_>) {
ben.iter(|| Duration::checked_seconds_f64(0.5));
ben.iter(|| Duration::checked_seconds_f64(-0.5));
}

fn checked_seconds_f32(ben: &mut Bencher<'_>) {
ben.iter(|| Duration::checked_seconds_f32(0.5));
ben.iter(|| Duration::checked_seconds_f32(-0.5));
}

fn milliseconds(ben: &mut Bencher<'_>) {
ben.iter(|| Duration::milliseconds(1));
ben.iter(|| Duration::milliseconds(-1));
Expand Down
70 changes: 70 additions & 0 deletions tests/duration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,12 +183,47 @@ fn whole_seconds() {
fn seconds_f64() {
assert_eq!(Duration::seconds_f64(0.5), 0.5.seconds());
assert_eq!(Duration::seconds_f64(-0.5), (-0.5).seconds());
assert_eq!(Duration::seconds_f64(123.250), 123.250.seconds());
assert_eq!(Duration::seconds_f64(0.000_000_000_012), Duration::ZERO);

assert_panic!(Duration::seconds_f64(f64::MAX));
assert_panic!(Duration::seconds_f64(f64::MIN));
assert_panic!(Duration::seconds_f64(f64::NAN));
}

#[test]
fn saturating_seconds_f64() {
assert_eq!(Duration::saturating_seconds_f64(0.5), 0.5.seconds());
assert_eq!(Duration::saturating_seconds_f64(-0.5), (-0.5).seconds());
assert_eq!(Duration::saturating_seconds_f64(123.250), 123.250.seconds());
assert_eq!(
Duration::saturating_seconds_f64(0.000_000_000_012),
Duration::ZERO
);

assert_eq!(Duration::saturating_seconds_f64(f64::MAX), Duration::MAX);
assert_eq!(Duration::saturating_seconds_f64(f64::MIN), Duration::MIN);
assert_eq!(Duration::saturating_seconds_f64(f64::NAN), Duration::ZERO);
}

#[test]
fn checked_seconds_f64() {
assert_eq!(Duration::checked_seconds_f64(0.5), Some(0.5.seconds()));
assert_eq!(Duration::checked_seconds_f64(-0.5), Some((-0.5).seconds()));
assert_eq!(
Duration::checked_seconds_f64(123.250),
Some(123.250.seconds())
);
assert_eq!(
Duration::checked_seconds_f64(0.000_000_000_012),
Some(Duration::ZERO)
);

assert_eq!(Duration::checked_seconds_f64(f64::MAX), None);
assert_eq!(Duration::checked_seconds_f64(f64::MIN), None);
assert_eq!(Duration::checked_seconds_f64(f64::NAN), None);
}

#[test]
#[allow(clippy::float_cmp)]
fn as_seconds_f64() {
Expand All @@ -204,12 +239,47 @@ fn as_seconds_f64() {
fn seconds_f32() {
assert_eq!(Duration::seconds_f32(0.5), 0.5.seconds());
assert_eq!(Duration::seconds_f32(-0.5), (-0.5).seconds());
assert_eq!(Duration::seconds_f32(123.250), 123.250.seconds());
assert_eq!(Duration::seconds_f32(0.000_000_000_012), Duration::ZERO);

assert_panic!(Duration::seconds_f32(f32::MAX));
assert_panic!(Duration::seconds_f32(f32::MIN));
assert_panic!(Duration::seconds_f32(f32::NAN));
}

#[test]
fn saturating_seconds_f32() {
assert_eq!(Duration::saturating_seconds_f32(0.5), 0.5.seconds());
assert_eq!(Duration::saturating_seconds_f32(-0.5), (-0.5).seconds());
assert_eq!(Duration::saturating_seconds_f32(123.250), 123.250.seconds());
assert_eq!(
Duration::saturating_seconds_f32(0.000_000_000_012),
Duration::ZERO
);

assert_eq!(Duration::saturating_seconds_f32(f32::MAX), Duration::MAX);
assert_eq!(Duration::saturating_seconds_f32(f32::MIN), Duration::MIN);
assert_eq!(Duration::saturating_seconds_f32(f32::NAN), Duration::ZERO);
}

#[test]
fn checked_seconds_f32() {
assert_eq!(Duration::checked_seconds_f32(0.5), Some(0.5.seconds()));
assert_eq!(Duration::checked_seconds_f32(-0.5), Some((-0.5).seconds()));
assert_eq!(
Duration::checked_seconds_f32(123.250),
Some(123.250.seconds())
);
assert_eq!(
Duration::checked_seconds_f32(0.000_000_000_012),
Some(Duration::ZERO)
);

assert_eq!(Duration::checked_seconds_f32(f32::MAX), None);
assert_eq!(Duration::checked_seconds_f32(f32::MIN), None);
assert_eq!(Duration::checked_seconds_f32(f32::NAN), None);
}

#[test]
#[allow(clippy::float_cmp)]
fn as_seconds_f32() {
Expand Down
Loading

0 comments on commit e83d01f

Please sign in to comment.