|
1 | 1 | use std::num::FpCategory as Fp;
|
2 | 2 | use std::ops::{Add, Div, Mul, Rem, Sub};
|
3 | 3 |
|
4 |
| -trait TestableFloat { |
| 4 | +trait TestableFloat: Sized { |
5 | 5 | /// Unsigned int with the same size, for converting to/from bits.
|
6 | 6 | type Int;
|
7 | 7 | /// Set the default tolerance for float comparison based on the type.
|
8 | 8 | const APPROX: Self;
|
| 9 | + /// Allow looser tolerance for f32 on miri |
| 10 | + const POWI_APPROX: Self = Self::APPROX; |
9 | 11 | const ZERO: Self;
|
10 | 12 | const ONE: Self;
|
11 | 13 | const MIN_POSITIVE_NORMAL: Self;
|
@@ -39,6 +41,10 @@ impl TestableFloat for f16 {
|
39 | 41 | impl TestableFloat for f32 {
|
40 | 42 | type Int = u32;
|
41 | 43 | const APPROX: Self = 1e-6;
|
| 44 | + /// Miri adds some extra errors to float functions; make sure the tests still pass. |
| 45 | + /// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides. |
| 46 | + /// They serve as a way to get an idea of the real precision of floating point operations on different platforms. |
| 47 | + const POWI_APPROX: Self = if cfg!(miri) { 1e-4 } else { Self::APPROX }; |
42 | 48 | const ZERO: Self = 0.0;
|
43 | 49 | const ONE: Self = 1.0;
|
44 | 50 | const MIN_POSITIVE_NORMAL: Self = Self::MIN_POSITIVE;
|
@@ -1360,3 +1366,24 @@ float_test! {
|
1360 | 1366 | assert_biteq!(neg_inf.recip(), -0.0);
|
1361 | 1367 | }
|
1362 | 1368 | }
|
| 1369 | + |
| 1370 | +float_test! { |
| 1371 | + name: powi, |
| 1372 | + attrs: { |
| 1373 | + const: #[cfg(false)], |
| 1374 | + f16: #[cfg(all(not(miri), target_has_reliable_f16_math))], |
| 1375 | + f128: #[cfg(all(not(miri), target_has_reliable_f128_math))], |
| 1376 | + }, |
| 1377 | + test<Float> { |
| 1378 | + let nan: Float = Float::NAN; |
| 1379 | + let inf: Float = Float::INFINITY; |
| 1380 | + let neg_inf: Float = Float::NEG_INFINITY; |
| 1381 | + assert_approx_eq!(Float::ONE.powi(1), Float::ONE); |
| 1382 | + assert_approx_eq!((-3.1 as Float).powi(2), 9.6100000000000005506706202140776519387, Float::POWI_APPROX); |
| 1383 | + assert_approx_eq!((5.9 as Float).powi(-2), 0.028727377190462507313100483690639638451); |
| 1384 | + assert_biteq!((8.3 as Float).powi(0), Float::ONE); |
| 1385 | + assert!(nan.powi(2).is_nan()); |
| 1386 | + assert_biteq!(inf.powi(3), inf); |
| 1387 | + assert_biteq!(neg_inf.powi(2), inf); |
| 1388 | + } |
| 1389 | +} |
0 commit comments