Skip to content

Commit 308458a

Browse files
committed
Auto merge of #1396 - RalfJung:float-cast-tests, r=RalfJung
copy some float cast tests from rustc The more the merrirer!
2 parents d2e283b + da6846c commit 308458a

File tree

1 file changed

+112
-1
lines changed

1 file changed

+112
-1
lines changed

tests/run-pass/float.rs

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#![feature(track_caller)]
1+
#![feature(track_caller, stmt_expr_attributes)]
22
use std::fmt::Debug;
33

44
// Helper function to avoid promotion so that this tests "run-time" casts, not CTFE.
@@ -78,6 +78,7 @@ fn test_both_cast<F, I>(x: F, y: I)
7878
fn main() {
7979
basic();
8080
casts();
81+
more_casts();
8182
ops();
8283
}
8384

@@ -334,3 +335,113 @@ fn ops() {
334335
assert_eq((-3.5_f64).copysign(-0.42), -3.5_f64);
335336
assert!(f64::NAN.copysign(1.0).is_nan());
336337
}
338+
339+
/// Tests taken from rustc test suite.
340+
///
341+
342+
// Poor-man's black-box
343+
#[inline(never)]
344+
fn black_box<T>(x: T) -> T { x }
345+
346+
macro_rules! test {
347+
($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => (
348+
// black_box disables constant evaluation to test run-time conversions:
349+
assert_eq!(black_box::<$src_ty>($val) as $dest_ty, $expected,
350+
"run-time {} -> {}", stringify!($src_ty), stringify!($dest_ty));
351+
352+
{
353+
const X: $src_ty = $val;
354+
const Y: $dest_ty = X as $dest_ty;
355+
assert_eq!(Y, $expected,
356+
"const eval {} -> {}", stringify!($src_ty), stringify!($dest_ty));
357+
}
358+
);
359+
360+
($fval:expr, f* -> $ity:ident, $ival:expr) => (
361+
test!($fval, f32 -> $ity, $ival);
362+
test!($fval, f64 -> $ity, $ival);
363+
)
364+
}
365+
366+
macro_rules! common_fptoi_tests {
367+
($fty:ident -> $($ity:ident)+) => ({ $(
368+
test!($fty::NAN, $fty -> $ity, 0);
369+
test!($fty::INFINITY, $fty -> $ity, $ity::MAX);
370+
test!($fty::NEG_INFINITY, $fty -> $ity, $ity::MIN);
371+
// These two tests are not solely float->int tests, in particular the latter relies on
372+
// `u128::MAX as f32` not being UB. But that's okay, since this file tests int->float
373+
// as well, the test is just slightly misplaced.
374+
test!($ity::MIN as $fty, $fty -> $ity, $ity::MIN);
375+
test!($ity::MAX as $fty, $fty -> $ity, $ity::MAX);
376+
test!(0., $fty -> $ity, 0);
377+
test!($fty::MIN_POSITIVE, $fty -> $ity, 0);
378+
test!(-0.9, $fty -> $ity, 0);
379+
test!(1., $fty -> $ity, 1);
380+
test!(42., $fty -> $ity, 42);
381+
)+ });
382+
383+
(f* -> $($ity:ident)+) => ({
384+
common_fptoi_tests!(f32 -> $($ity)+);
385+
common_fptoi_tests!(f64 -> $($ity)+);
386+
})
387+
}
388+
389+
macro_rules! fptoui_tests {
390+
($fty: ident -> $($ity: ident)+) => ({ $(
391+
test!(-0., $fty -> $ity, 0);
392+
test!(-$fty::MIN_POSITIVE, $fty -> $ity, 0);
393+
test!(-0.99999994, $fty -> $ity, 0);
394+
test!(-1., $fty -> $ity, 0);
395+
test!(-100., $fty -> $ity, 0);
396+
test!(#[allow(overflowing_literals)] -1e50, $fty -> $ity, 0);
397+
test!(#[allow(overflowing_literals)] -1e130, $fty -> $ity, 0);
398+
)+ });
399+
400+
(f* -> $($ity:ident)+) => ({
401+
fptoui_tests!(f32 -> $($ity)+);
402+
fptoui_tests!(f64 -> $($ity)+);
403+
})
404+
}
405+
406+
fn more_casts() {
407+
common_fptoi_tests!(f* -> i8 i16 i32 i64 u8 u16 u32 u64);
408+
fptoui_tests!(f* -> u8 u16 u32 u64);
409+
common_fptoi_tests!(f* -> i128 u128);
410+
fptoui_tests!(f* -> u128);
411+
412+
// The following tests cover edge cases for some integer types.
413+
414+
// # u8
415+
test!(254., f* -> u8, 254);
416+
test!(256., f* -> u8, 255);
417+
418+
// # i8
419+
test!(-127., f* -> i8, -127);
420+
test!(-129., f* -> i8, -128);
421+
test!(126., f* -> i8, 126);
422+
test!(128., f* -> i8, 127);
423+
424+
// # i32
425+
// -2147483648. is i32::MIN (exactly)
426+
test!(-2147483648., f* -> i32, i32::MIN);
427+
// 2147483648. is i32::MAX rounded up
428+
test!(2147483648., f32 -> i32, 2147483647);
429+
// With 24 significand bits, floats with magnitude in [2^30 + 1, 2^31] are rounded to
430+
// multiples of 2^7. Therefore, nextDown(round(i32::MAX)) is 2^31 - 128:
431+
test!(2147483520., f32 -> i32, 2147483520);
432+
// Similarly, nextUp(i32::MIN) is i32::MIN + 2^8 and nextDown(i32::MIN) is i32::MIN - 2^7
433+
test!(-2147483904., f* -> i32, i32::MIN);
434+
test!(-2147483520., f* -> i32, -2147483520);
435+
436+
// # u32
437+
// round(MAX) and nextUp(round(MAX))
438+
test!(4294967040., f* -> u32, 4294967040);
439+
test!(4294967296., f* -> u32, 4294967295);
440+
441+
// # u128
442+
// float->int:
443+
test!(f32::MAX, f32 -> u128, 0xffffff00000000000000000000000000);
444+
// nextDown(f32::MAX) = 2^128 - 2 * 2^104
445+
const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.;
446+
test!(SECOND_LARGEST_F32, f32 -> u128, 0xfffffe00000000000000000000000000);
447+
}

0 commit comments

Comments
 (0)