1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // Tests saturating float->int casts. See u128-as-f32.rs for the opposite direction.
12 // compile-flags: -Z saturating-float-casts
14 #![feature(test, i128, i128_type, stmt_expr_attributes)]
15 #![deny(overflowing_literals)]
19 use std
::{u8, i8, u16, i16, u32, i32, u64, i64}
;
20 #[cfg(not(target_os="emscripten"))]
21 use std
::{u128, i128}
;
25 ($val
:expr
, $src_ty
:ident
-> $dest_ty
:ident
, $expected
:expr
) => (
26 // black_box disables constant evaluation to test run-time conversions:
27 assert_eq
!(black_box
::<$src_ty
>($val
) as $dest_ty
, $expected
,
28 "run-time {} -> {}", stringify
!($src_ty
), stringify
!($dest_ty
));
31 ($fval
:expr
, f
* -> $ity
:ident
, $ival
:expr
) => (
32 test
!($fval
, f32 -> $ity
, $ival
);
33 test
!($fval
, f64 -> $ity
, $ival
);
37 // This macro tests const eval in addition to run-time evaluation.
38 // If and when saturating casts are adopted, this macro should be merged with test!() to ensure
39 // that run-time and const eval agree on inputs that currently trigger a const eval error.
41 ($val
:expr
, $src_ty
:ident
-> $dest_ty
:ident
, $expected
:expr
) => ({
42 test
!($val
, $src_ty
-> $dest_ty
, $expected
);
44 const X
: $src_ty
= $val
;
45 const Y
: $dest_ty
= X
as $dest_ty
;
46 assert_eq
!(Y
, $expected
,
47 "const eval {} -> {}", stringify
!($src_ty
), stringify
!($dest_ty
));
51 ($fval
:expr
, f
* -> $ity
:ident
, $ival
:expr
) => (
52 test_c
!($fval
, f32 -> $ity
, $ival
);
53 test_c
!($fval
, f64 -> $ity
, $ival
);
57 macro_rules
! common_fptoi_tests
{
58 ($fty
:ident
-> $
($ity
:ident
)+) => ({ $
(
59 test
!($fty
::NAN
, $fty
-> $ity
, 0);
60 test
!($fty
::INFINITY
, $fty
-> $ity
, $ity
::MAX
);
61 test
!($fty
::NEG_INFINITY
, $fty
-> $ity
, $ity
::MIN
);
62 // These two tests are not solely float->int tests, in particular the latter relies on
63 // `u128::MAX as f32` not being UB. But that's okay, since this file tests int->float
64 // as well, the test is just slightly misplaced.
65 test
!($ity
::MIN
as $fty
, $fty
-> $ity
, $ity
::MIN
);
66 test
!($ity
::MAX
as $fty
, $fty
-> $ity
, $ity
::MAX
);
67 test_c
!(0., $fty
-> $ity
, 0);
68 test_c
!($fty
::MIN_POSITIVE
, $fty
-> $ity
, 0);
69 test
!(-0.9, $fty
-> $ity
, 0);
70 test_c
!(1., $fty
-> $ity
, 1);
71 test_c
!(42., $fty
-> $ity
, 42);
74 (f
* -> $
($ity
:ident
)+) => ({
75 common_fptoi_tests
!(f32 -> $
($ity
)+);
76 common_fptoi_tests
!(f64 -> $
($ity
)+);
80 macro_rules
! fptoui_tests
{
81 ($fty
: ident
-> $
($ity
: ident
)+) => ({ $
(
82 test
!(-0., $fty
-> $ity
, 0);
83 test
!(-$fty
::MIN_POSITIVE
, $fty
-> $ity
, 0);
84 test
!(-0.99999994, $fty
-> $ity
, 0);
85 test
!(-1., $fty
-> $ity
, 0);
86 test
!(-100., $fty
-> $ity
, 0);
87 test
!(#[allow(overflowing_literals)] -1e50, $fty -> $ity, 0);
88 test
!(#[allow(overflowing_literals)] -1e130, $fty -> $ity, 0);
91 (f
* -> $
($ity
:ident
)+) => ({
92 fptoui_tests
!(f32 -> $
($ity
)+);
93 fptoui_tests
!(f64 -> $
($ity
)+);
98 common_fptoi_tests
!(f
* -> i8 i16 i32 i64 u8 u16 u32 u64);
99 fptoui_tests
!(f
* -> u8 u16 u32 u64);
100 // FIXME emscripten does not support i128
101 #[cfg(not(target_os="emscripten"))] {
102 common_fptoi_tests
!(f
* -> i128 u128
);
103 fptoui_tests
!(f
* -> u128
);
106 // The following tests cover edge cases for some integer types.
109 test_c
!(254., f
* -> u8, 254);
110 test
!(256., f
* -> u8, 255);
113 test_c
!(-127., f
* -> i8, -127);
114 test
!(-129., f
* -> i8, -128);
115 test_c
!(126., f
* -> i8, 126);
116 test
!(128., f
* -> i8, 127);
119 // -2147483648. is i32::MIN (exactly)
120 test_c
!(-2147483648., f
* -> i32, i32::MIN
);
121 // 2147483648. is i32::MAX rounded up
122 test
!(2147483648., f32 -> i32, 2147483647);
123 // With 24 significand bits, floats with magnitude in [2^30 + 1, 2^31] are rounded to
124 // multiples of 2^7. Therefore, nextDown(round(i32::MAX)) is 2^31 - 128:
125 test_c
!(2147483520., f32 -> i32, 2147483520);
126 // Similarly, nextUp(i32::MIN) is i32::MIN + 2^8 and nextDown(i32::MIN) is i32::MIN - 2^7
127 test
!(-2147483904., f
* -> i32, i32::MIN
);
128 test_c
!(-2147483520., f
* -> i32, -2147483520);
131 // round(MAX) and nextUp(round(MAX))
132 test_c
!(4294967040., f
* -> u32, 4294967040);
133 test
!(4294967296., f
* -> u32, 4294967295);
136 #[cfg(not(target_os="emscripten"))]
139 test_c
!(f32::MAX
, f32 -> u128
, 0xffffff00000000000000000000000000);
140 // nextDown(f32::MAX) = 2^128 - 2 * 2^104
141 const SECOND_LARGEST_F32
: f32 = 340282326356119256160033759537265639424.;
142 test_c
!(SECOND_LARGEST_F32
, f32 -> u128
, 0xfffffe00000000000000000000000000);