diff options
| author | Ruan Comelli <ruancomelli@gmail.com> | 2025-05-19 18:34:32 -0300 |
|---|---|---|
| committer | Ruan Comelli <ruancomelli@gmail.com> | 2025-05-31 15:26:57 -0300 |
| commit | f8e97badb26f1436d062b3bfdd4f50adc41b843a (patch) | |
| tree | a29a0bc6645cebe112c818d0c9ec007da6b0b314 /library/coretests/tests/num/mod.rs | |
| parent | 852f15c0f146fc292c9b20f2a8f44c1f671d7845 (diff) | |
| download | rust-f8e97badb26f1436d062b3bfdd4f50adc41b843a.tar.gz rust-f8e97badb26f1436d062b3bfdd4f50adc41b843a.zip | |
Add const support for float rounding methods
Add const support for the float rounding methods floor, ceil, trunc,
fract, round and round_ties_even.
This works by moving the calculation logic from
src/tools/miri/src/intrinsics/mod.rs
into
compiler/rustc_const_eval/src/interpret/intrinsics.rs.
All relevant method definitions were adjusted to include the `const`
keyword for all supported float types: f16, f32, f64 and f128.
The constness is hidden behind the feature gate
feature(const_float_round_methods)
which is tracked in
https://github.com/rust-lang/rust/issues/141555
This commit is a squash of the following commits:
- test: add tests that we expect to pass when float rounding becomes const
- feat: make float rounding methods `const`
- fix: replace `rustc_allow_const_fn_unstable(core_intrinsics)` attribute with `#[rustc_const_unstable(feature = "f128", issue = "116909")]` in `library/core/src/num/f128.rs`
- revert: undo update to `library/stdarch`
- refactor: replace multiple `float_<mode>_intrinsic` rounding methods with a single, parametrized one
- fix: add `#[cfg(not(bootstrap))]` to new const method tests
- test: add extra sign tests to check `+0.0` and `-0.0`
- revert: undo accidental changes to `round` docs
- fix: gate `const` float round method behind `const_float_round_methods`
- fix: remove unnecessary `#![feature(const_float_methods)]`
- fix: remove unnecessary `#![feature(const_float_methods)]` [2]
- revert: undo changes to `tests/ui/consts/const-eval/float_methods.rs`
- fix: adjust after rebase
- test: fix float tests
- test: add tests for `fract`
- chore: add commented-out `const_float_round_methods` feature gates to `f16` and `f128`
- fix: adjust NaN when rounding floats
- chore: add FIXME comment for de-duplicating float tests
- test: remove unnecessary test file `tests/ui/consts/const-eval/float_methods.rs`
- test: fix tests after upstream simplification of how float tests are run
Diffstat (limited to 'library/coretests/tests/num/mod.rs')
| -rw-r--r-- | library/coretests/tests/num/mod.rs | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/library/coretests/tests/num/mod.rs b/library/coretests/tests/num/mod.rs index 1212d36a1b1..fa05bbdd9b7 100644 --- a/library/coretests/tests/num/mod.rs +++ b/library/coretests/tests/num/mod.rs @@ -731,6 +731,9 @@ assume_usize_width! { } } +// FIXME(141726): there is a lot of duplication between the following tests and +// the tests in `coretests/tests/floats/f*.rs` +// See issue https://github.com/rust-lang/rust/issues/141726 for more details. macro_rules! test_float { ($modname: ident, $fassert: ident, $fty: ty) => { mod $modname { @@ -947,6 +950,117 @@ macro_rules! test_float { assert!(<$fty>::INFINITY.div_euclid(<$fty>::NAN).is_nan()); assert!(<$fty>::NAN.div_euclid(<$fty>::INFINITY).is_nan()); } + #[test] + #[cfg(not(bootstrap))] + fn floor() { + $fassert!((0.0 as $fty).floor(), 0.0); + $fassert!((0.0 as $fty).floor().is_sign_positive()); + $fassert!((-0.0 as $fty).floor(), -0.0); + $fassert!((-0.0 as $fty).floor().is_sign_negative()); + $fassert!((0.5 as $fty).floor(), 0.0); + $fassert!((-0.5 as $fty).floor(), -1.0); + $fassert!((1.5 as $fty).floor(), 1.0); + $fassert!(<$fty>::MAX.floor(), <$fty>::MAX); + $fassert!(<$fty>::MIN.floor(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.floor(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).floor(), -1.0); + $fassert!(<$fty>::NAN.floor().is_nan()); + $fassert!(<$fty>::INFINITY.floor(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.floor(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn ceil() { + $fassert!((0.0 as $fty).ceil(), 0.0); + $fassert!((0.0 as $fty).ceil().is_sign_positive()); + $fassert!((-0.0 as $fty).ceil(), 0.0); + $fassert!((-0.0 as $fty).ceil().is_sign_negative()); + $fassert!((0.5 as $fty).ceil(), 1.0); + $fassert!((-0.5 as $fty).ceil(), 0.0); + $fassert!(<$fty>::MAX.ceil(), <$fty>::MAX); + $fassert!(<$fty>::MIN.ceil(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.ceil(), 1.0); + $fassert!((-<$fty>::MIN_POSITIVE).ceil(), 0.0); + $fassert!(<$fty>::NAN.ceil().is_nan()); + $fassert!(<$fty>::INFINITY.ceil(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.ceil(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn round() { + $fassert!((0.0 as $fty).round(), 0.0); + $fassert!((0.0 as $fty).round().is_sign_positive()); + $fassert!((-0.0 as $fty).round(), -0.0); + $fassert!((-0.0 as $fty).round().is_sign_negative()); + $fassert!((0.5 as $fty).round(), 1.0); + $fassert!((-0.5 as $fty).round(), -1.0); + $fassert!(<$fty>::MAX.round(), <$fty>::MAX); + $fassert!(<$fty>::MIN.round(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.round(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).round(), 0.0); + $fassert!(<$fty>::NAN.round().is_nan()); + $fassert!(<$fty>::INFINITY.round(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.round(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn round_ties_even() { + $fassert!((0.0 as $fty).round_ties_even(), 0.0); + $fassert!((0.0 as $fty).round_ties_even().is_sign_positive()); + $fassert!((-0.0 as $fty).round_ties_even(), -0.0); + $fassert!((-0.0 as $fty).round_ties_even().is_sign_negative()); + $fassert!((0.5 as $fty).round_ties_even(), 0.0); + $fassert!((0.5 as $fty).round_ties_even().is_sign_positive()); + $fassert!((-0.5 as $fty).round_ties_even(), -0.0); + $fassert!((-0.5 as $fty).round_ties_even().is_sign_negative()); + $fassert!(<$fty>::MAX.round_ties_even(), <$fty>::MAX); + $fassert!(<$fty>::MIN.round_ties_even(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.round_ties_even(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).round_ties_even(), 0.0); + $fassert!(<$fty>::NAN.round_ties_even().is_nan()); + $fassert!(<$fty>::INFINITY.round_ties_even(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.round_ties_even(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn trunc() { + $fassert!((0.0 as $fty).trunc(), 0.0); + $fassert!((0.0 as $fty).trunc().is_sign_positive()); + $fassert!((-0.0 as $fty).trunc(), -0.0); + $fassert!((-0.0 as $fty).trunc().is_sign_negative()); + $fassert!((0.5 as $fty).trunc(), 0.0); + $fassert!((0.5 as $fty).trunc().is_sign_positive()); + $fassert!((-0.5 as $fty).trunc(), -0.0); + $fassert!((-0.5 as $fty).trunc().is_sign_negative()); + $fassert!(<$fty>::MAX.trunc(), <$fty>::MAX); + $fassert!(<$fty>::MIN.trunc(), <$fty>::MIN); + $fassert!(<$fty>::MIN_POSITIVE.trunc(), 0.0); + $fassert!((-<$fty>::MIN_POSITIVE).trunc(), 0.0); + $fassert!(<$fty>::NAN.trunc().is_nan()); + $fassert!(<$fty>::INFINITY.trunc(), <$fty>::INFINITY); + $fassert!(<$fty>::NEG_INFINITY.trunc(), <$fty>::NEG_INFINITY); + } + #[test] + #[cfg(not(bootstrap))] + fn fract() { + $fassert!((0.0 as $fty).fract(), 0.0); + $fassert!((0.0 as $fty).fract().is_sign_positive()); + $fassert!((-0.0 as $fty).fract(), 0.0); + $fassert!((-0.0 as $fty).fract().is_sign_positive()); + $fassert!((0.5 as $fty).fract(), 0.5); + $fassert!((0.5 as $fty).fract().is_sign_positive()); + $fassert!((-0.5 as $fty).fract(), -0.5); + $fassert!((-0.5 as $fty).fract().is_sign_negative()); + $fassert!(<$fty>::MAX.fract(), 0.0); + $fassert!(<$fty>::MIN.fract(), 0.0); + $fassert!(<$fty>::MIN_POSITIVE.fract(), <$fty>::MIN_POSITIVE); + $fassert!(<$fty>::MIN_POSITIVE.fract().is_sign_positive()); + $fassert!((-<$fty>::MIN_POSITIVE).fract(), -<$fty>::MIN_POSITIVE); + $fassert!((-<$fty>::MIN_POSITIVE).fract().is_sign_negative()); + $fassert!(<$fty>::NAN.fract().is_nan()); + $fassert!(<$fty>::INFINITY.fract().is_nan()); + $fassert!(<$fty>::NEG_INFINITY.fract().is_nan()); + } } }; } |
