Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions tests/run-pass/floats.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,84 @@
fn main() {
// basic arithmetic
assert_eq!(6.0_f32*6.0_f32, 36.0_f32);
assert_eq!(6.0_f64*6.0_f64, 36.0_f64);
assert_eq!(-{5.0_f32}, -5.0_f32);
assert_eq!(-{5.0_f64}, -5.0_f64);
// infinities, NaN
assert!((5.0_f32/0.0).is_infinite());
assert!((5.0_f64/0.0).is_infinite());
assert!((-5.0_f32).sqrt().is_nan());
assert!((-5.0_f64).sqrt().is_nan());
// byte-level transmute
let x: u64 = unsafe { std::mem::transmute(42.0_f64) };
let y: f64 = unsafe { std::mem::transmute(x) };
assert_eq!(y, 42.0_f64);
let x: u32 = unsafe { std::mem::transmute(42.0_f32) };
let y: f32 = unsafe { std::mem::transmute(x) };
assert_eq!(y, 42.0_f32);

// f32 casts
assert_eq!(5.0f32 as u32, 5);
assert_eq!(-5.0f32 as u32, 0);
assert_eq!(5.0f32 as i32, 5);
assert_eq!(-5.0f32 as i32, -5);
assert_eq!(std::f32::MAX as i32, i32::MAX);
assert_eq!(std::f32::INFINITY as i32, i32::MAX);
assert_eq!(std::f32::MAX as u32, u32::MAX);
assert_eq!(std::f32::INFINITY as u32, u32::MAX);
assert_eq!(std::f32::MIN as i32, i32::MIN);
assert_eq!(std::f32::NEG_INFINITY as i32, i32::MIN);
assert_eq!(std::f32::MIN as u32, 0);
assert_eq!(std::f32::NEG_INFINITY as u32, 0);
assert_eq!(std::f32::NAN as i32, 0);
assert_eq!(std::f32::NAN as u32, 0);
assert_eq!(u128::MAX as f32, std::f32::INFINITY);
assert_eq!((u32::MAX-127) as f32 as u32, u32::MAX); // rounding loss
assert_eq!((u32::MAX-128) as f32 as u32, u32::MAX-255); // rounding loss
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hanna-kruppe do these two (and the two "rounding loss" tests below) look like correct behavior to you? I experimentally determined these to be the closest to u32::MAX where the output of the roundtrip cast changes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jodysankey you also seem to know floating point encoding stuff quite well, would be nice if you could have a look.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they look exactly right to me. These are transition points from "odd significant + slightly less than 0.5 ULP" (which gets rounded down to uint::MAX - 1 ULP) to "odd significant + 0.5 ULP" (which is rounded up, so saturation kicks in when casting back to integer).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hanna-kruppe I only understood half of that, but that half sounds good. ;) Thanks!


// f64 casts
assert_eq!(5.0f64 as u64, 5);
assert_eq!(-5.0f64 as u64, 0);
assert_eq!(5.0f64 as i64, 5);
assert_eq!(-5.0f64 as i64, -5);
assert_eq!(std::f64::MAX as i64, i64::MAX);
assert_eq!(std::f64::INFINITY as i64, i64::MAX);
assert_eq!(std::f64::MAX as u64, u64::MAX);
assert_eq!(std::f64::INFINITY as u64, u64::MAX);
assert_eq!(std::f64::MIN as i64, i64::MIN);
assert_eq!(std::f64::NEG_INFINITY as i64, i64::MIN);
assert_eq!(std::f64::MIN as u64, 0);
assert_eq!(std::f64::NEG_INFINITY as u64, 0);
assert_eq!(std::f64::NAN as i64, 0);
assert_eq!(std::f64::NAN as u64, 0);
assert_eq!(u128::MAX as f64 as u128, u128::MAX);
assert_eq!((u64::MAX-1023) as f64 as u64, u64::MAX); // rounding loss
assert_eq!((u64::MAX-1024) as f64 as u64, u64::MAX-2047); // rounding loss

// f32 min/max
assert_eq!((1.0 as f32).max(-1.0), 1.0);
assert_eq!((1.0 as f32).min(-1.0), -1.0);
assert_eq!(std::f32::NAN.min(9.0), 9.0);
assert_eq!(std::f32::NAN.max(-9.0), -9.0);
assert_eq!((9.0 as f32).min(std::f32::NAN), 9.0);
assert_eq!((-9.0 as f32).max(std::f32::NAN), -9.0);

// f64 min/max
assert_eq!((1.0 as f64).max(-1.0), 1.0);
assert_eq!((1.0 as f64).min(-1.0), -1.0);
assert_eq!(std::f64::NAN.min(9.0), 9.0);
assert_eq!(std::f64::NAN.max(-9.0), -9.0);
assert_eq!((9.0 as f64).min(std::f64::NAN), 9.0);
assert_eq!((-9.0 as f64).max(std::f64::NAN), -9.0);

// f32 copysign
assert_eq!(3.5_f32.copysign(0.42), 3.5_f32);
assert_eq!(3.5_f32.copysign(-0.42), -3.5_f32);
assert_eq!((-3.5_f32).copysign(0.42), 3.5_f32);
assert_eq!((-3.5_f32).copysign(-0.42), -3.5_f32);
assert!(std::f32::NAN.copysign(1.0).is_nan());

// f64 copysign
assert_eq!(3.5_f64.copysign(0.42), 3.5_f64);
assert_eq!(3.5_f64.copysign(-0.42), -3.5_f64);
assert_eq!((-3.5_f64).copysign(0.42), 3.5_f64);
Expand Down