float_next_after

Crates.iofloat_next_after
lib.rsfloat_next_after
version1.0.0
sourcesrc
created_at2020-04-08 23:51:02.122075
updated_at2022-12-11 23:25:01.69627
descriptionA trait for native rust f64/f32 nextafter
homepagehttps://gitlab.com/bronsonbdevost/next_afterf
repositoryhttps://gitlab.com/bronsonbdevost/next_afterf
max_upload_size
id227780
size22,031
Bronson Brown-deVost (Bronson-Brown-deVost)

documentation

README

float-next-after

codecov Documentation License: MIT Crates.io Crates.io

A native Rust next after float function, which is provided as a trait for f32 and f64 types. It steps to the next representable floating point, even if it is subnormal. If a subnormal is undesired, users should handle that eventuality themselves. See CHANGES.md for the versioned changelog.

In specific edge cases the following decisions have been made:

  • self == y -> return y
  • self >= positive infinity -> return positive infinity
  • self <= negative infinity -> return negative infinity
  • self or y == NaN -> return NaN
  • self = -0.0 and y = 0.0 -> return positive 0.0
  • self == -0.0 and y == positive infinity -> 5e-324

Please see the unit tests for the actual behavior in various other exceptional cases.

This code uses the ToBits and FromBits functions from f32 and f64. Those both simply wrap unsafe { mem::transmute(self) } / unsafe { mem::transmute(v) } to convert a f32/f64 to u32/u64. The docs for those functions, however, claim that they are safe and that "the safety issues with sNaN were overblown!"

PR's and other helpful input are welcome.

Usage

use float_next_after::NextAfter;

// Large numbers
let big_num = 16237485966.00000437586943_f64;
let next = big_num.next_after(std::f64::INFINITY);
assert_eq!(next, 16237485966.000006_f64);

// Expected handling of 1.0
let one = 1_f64;
let next = one.next_after(std::f64::INFINITY);
assert_eq!(next, 1_f64 + std::f64::EPSILON);

// Tiny (negative) numbers
let zero = 0_f32;
let next = zero.next_after(std::f32::NEG_INFINITY);
assert_eq!(next, -0.000000000000000000000000000000000000000000001_f32);

// Equal source/dest (even -0 == 0)
let zero = 0_f64;
let next = zero.next_after(-0_f64);
assert_eq!(next, -0_f64);
Commit count: 51

cargo fmt