Skip to content

Commit eeca284

Browse files
change tests to use fixed constants to let them pass with miri
1 parent 5c32366 commit eeca284

File tree

7 files changed

+54
-76
lines changed

7 files changed

+54
-76
lines changed

library/core/src/num/f32.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,7 @@ pub mod math {
18731873
///
18741874
/// let x = 2.0_f32;
18751875
/// let abs_difference = (f32::math::powi(x, 2) - (x * x)).abs();
1876-
/// assert!(abs_difference <= 8.0 * f32::EPSILON);
1876+
/// assert!(abs_difference <= 1e-5);
18771877
///
18781878
/// assert_eq!(f32::math::powi(f32::NAN, 0), 1.0);
18791879
/// ```

library/core/src/num/f64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1871,7 +1871,7 @@ pub mod math {
18711871
///
18721872
/// let x = 2.0_f64;
18731873
/// let abs_difference = (f64::math::powi(x, 2) - (x * x)).abs();
1874-
/// assert!(abs_difference <= 8.0 * f64::EPSILON);
1874+
/// assert!(abs_difference <= 1e-6);
18751875
///
18761876
/// assert_eq!(f64::math::powi(f64::NAN, 0), 1.0);
18771877
/// ```

library/coretests/tests/floats/f32.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,22 @@ const NAN_MASK1: u32 = 0x002a_aaaa;
2323
/// Second pattern over the mantissa
2424
const NAN_MASK2: u32 = 0x0055_5555;
2525

26+
/// Miri adds some extra errors to float functions; make sure the tests still pass.
27+
/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides.
28+
/// They serve as a way to get an idea of the real precision of floating point operations on different platforms.
29+
const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 };
30+
31+
#[allow(unused_macros)]
32+
macro_rules! assert_f32_biteq {
33+
($left : expr, $right : expr) => {
34+
let l: &f32 = &$left;
35+
let r: &f32 = &$right;
36+
let lb = l.to_bits();
37+
let rb = r.to_bits();
38+
assert_eq!(lb, rb, "float {l} ({lb:#010x}) is not bitequal to {r} ({rb:#010x})");
39+
};
40+
}
41+
2642
#[test]
2743
fn test_num_f32() {
2844
super::test_num(10f32, 2f32);
@@ -437,8 +453,8 @@ fn test_powi() {
437453
let nan: f32 = f32::NAN;
438454
let inf: f32 = f32::INFINITY;
439455
let neg_inf: f32 = f32::NEG_INFINITY;
440-
assert_biteq!(1.0f32.powi(1), 1.0);
441-
assert_approx_eq!((-3.1f32).powi(2), 9.61);
456+
assert_approx_eq!(1.0f32.powi(1), 1.0);
457+
assert_approx_eq!((-3.1f32).powi(2), 9.61, APPROX_DELTA);
442458
assert_approx_eq!(5.9f32.powi(-2), 0.028727);
443459
assert_biteq!(8.3f32.powi(0), 1.0);
444460
assert!(nan.powi(2).is_nan());

library/std/src/num/f32.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ impl f32 {
298298
/// ```
299299
/// let x = 2.0_f32;
300300
/// let abs_difference = (x.powi(2) - (x * x)).abs();
301-
/// assert!(abs_difference <= 8.0 * f32::EPSILON);
301+
/// assert!(abs_difference <= 1e-5);
302302
///
303303
/// assert_eq!(f32::powi(f32::NAN, 0), 1.0);
304304
/// ```
@@ -322,7 +322,7 @@ impl f32 {
322322
/// ```
323323
/// let x = 2.0_f32;
324324
/// let abs_difference = (x.powf(2.0) - (x * x)).abs();
325-
/// assert!(abs_difference <= 8.0 * f32::EPSILON);
325+
/// assert!(abs_difference <= 1e-5);
326326
///
327327
/// assert_eq!(f32::powf(1.0, f32::NAN), 1.0);
328328
/// assert_eq!(f32::powf(f32::NAN, 0.0), 1.0);
@@ -382,7 +382,7 @@ impl f32 {
382382
/// // ln(e) - 1 == 0
383383
/// let abs_difference = (e.ln() - 1.0).abs();
384384
///
385-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
385+
/// assert!(abs_difference <= 1e-6);
386386
/// ```
387387
#[rustc_allow_incoherent_impl]
388388
#[must_use = "method returns a new number and does not mutate the original value"]
@@ -407,7 +407,7 @@ impl f32 {
407407
/// // 2^2 - 4 == 0
408408
/// let abs_difference = (f.exp2() - 4.0).abs();
409409
///
410-
/// assert!(abs_difference <= 8.0 * f32::EPSILON);
410+
/// assert!(abs_difference <= 1e-5);
411411
/// ```
412412
#[rustc_allow_incoherent_impl]
413413
#[must_use = "method returns a new number and does not mutate the original value"]
@@ -436,7 +436,7 @@ impl f32 {
436436
/// // ln(e) - 1 == 0
437437
/// let abs_difference = (e.ln() - 1.0).abs();
438438
///
439-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
439+
/// assert!(abs_difference <= 1e-6);
440440
/// ```
441441
///
442442
/// Non-positive values:
@@ -473,7 +473,7 @@ impl f32 {
473473
/// // log5(5) - 1 == 0
474474
/// let abs_difference = (five.log(5.0) - 1.0).abs();
475475
///
476-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
476+
/// assert!(abs_difference <= 1e-6);
477477
/// ```
478478
///
479479
/// Non-positive values:
@@ -506,7 +506,7 @@ impl f32 {
506506
/// // log2(2) - 1 == 0
507507
/// let abs_difference = (two.log2() - 1.0).abs();
508508
///
509-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
509+
/// assert!(abs_difference <= 1e-6);
510510
/// ```
511511
///
512512
/// Non-positive values:
@@ -539,7 +539,7 @@ impl f32 {
539539
/// // log10(10) - 1 == 0
540540
/// let abs_difference = (ten.log10() - 1.0).abs();
541541
///
542-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
542+
/// assert!(abs_difference <= 1e-6);
543543
/// ```
544544
///
545545
/// Non-positive values:
@@ -646,7 +646,7 @@ impl f32 {
646646
/// // sqrt(x^2 + y^2)
647647
/// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
648648
///
649-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
649+
/// assert!(abs_difference <= 1e-6);
650650
/// ```
651651
#[rustc_allow_incoherent_impl]
652652
#[must_use = "method returns a new number and does not mutate the original value"]
@@ -670,7 +670,7 @@ impl f32 {
670670
///
671671
/// let abs_difference = (x.sin() - 1.0).abs();
672672
///
673-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
673+
/// assert!(abs_difference <= 1e-6);
674674
/// ```
675675
#[rustc_allow_incoherent_impl]
676676
#[must_use = "method returns a new number and does not mutate the original value"]
@@ -694,7 +694,7 @@ impl f32 {
694694
///
695695
/// let abs_difference = (x.cos() - 1.0).abs();
696696
///
697-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
697+
/// assert!(abs_difference <= 1e-6);
698698
/// ```
699699
#[rustc_allow_incoherent_impl]
700700
#[must_use = "method returns a new number and does not mutate the original value"]
@@ -748,7 +748,7 @@ impl f32 {
748748
/// // asin(sin(pi/2))
749749
/// let abs_difference = (f.sin().asin() - std::f32::consts::FRAC_PI_2).abs();
750750
///
751-
/// // assert!(abs_difference <= 12.0 * f32::EPSILON);
751+
/// assert!(abs_difference <= 1e-3);
752752
/// ```
753753
#[doc(alias = "arcsin")]
754754
#[rustc_allow_incoherent_impl]
@@ -778,7 +778,7 @@ impl f32 {
778778
/// // acos(cos(pi/4))
779779
/// let abs_difference = (f.cos().acos() - std::f32::consts::FRAC_PI_4).abs();
780780
///
781-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
781+
/// assert!(abs_difference <= 1e-6);
782782
/// ```
783783
#[doc(alias = "arccos")]
784784
#[rustc_allow_incoherent_impl]
@@ -878,8 +878,8 @@ impl f32 {
878878
/// let abs_difference_0 = (f.0 - x.sin()).abs();
879879
/// let abs_difference_1 = (f.1 - x.cos()).abs();
880880
///
881-
/// assert!(abs_difference_0 <= 4.0 * f32::EPSILON);
882-
/// assert!(abs_difference_1 <= 4.0 * f32::EPSILON);
881+
/// assert!(abs_difference_0 <= 1e-6);
882+
/// assert!(abs_difference_1 <= 1e-6);
883883
/// ```
884884
#[doc(alias = "sincos")]
885885
#[rustc_allow_incoherent_impl]
@@ -1061,7 +1061,7 @@ impl f32 {
10611061
///
10621062
/// let abs_difference = (f - x).abs();
10631063
///
1064-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
1064+
/// assert!(abs_difference <= 1e-7);
10651065
/// ```
10661066
#[doc(alias = "arcsinh")]
10671067
#[rustc_allow_incoherent_impl]
@@ -1089,7 +1089,7 @@ impl f32 {
10891089
///
10901090
/// let abs_difference = (f - x).abs();
10911091
///
1092-
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
1092+
/// assert!(abs_difference <= 1e-6);
10931093
/// ```
10941094
#[doc(alias = "arccosh")]
10951095
#[rustc_allow_incoherent_impl]

library/std/src/num/f64.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ impl f64 {
298298
/// ```
299299
/// let x = 2.0_f64;
300300
/// let abs_difference = (x.powi(2) - (x * x)).abs();
301-
/// assert!(abs_difference <= 8.0 * f64::EPSILON);
301+
/// assert!(abs_difference <= 1e-14);
302302
///
303303
/// assert_eq!(f64::powi(f64::NAN, 0), 1.0);
304304
/// ```
@@ -322,7 +322,7 @@ impl f64 {
322322
/// ```
323323
/// let x = 2.0_f64;
324324
/// let abs_difference = (x.powf(2.0) - (x * x)).abs();
325-
/// assert!(abs_difference <= 8.0 * f64::EPSILON);
325+
/// assert!(abs_difference <= 1e-14);
326326
///
327327
/// assert_eq!(f64::powf(1.0, f64::NAN), 1.0);
328328
/// assert_eq!(f64::powf(f64::NAN, 0.0), 1.0);

library/std/tests/floats/f32.rs

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::f32::consts;
33
/// Miri adds some extra errors to float functions; make sure the tests still pass.
44
/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides.
55
/// They serve as a way to get an idea of the real precision of floating point operations on different platforms.
6-
const APPROX_DELTA: f32 = if cfg!(miri) { 1e-4 } else { 1e-6 };
6+
const APPROX_DELTA: f32 = if cfg!(miri) { 1e-3 } else { 1e-6 };
77

88
#[allow(unused_macros)]
99
macro_rules! assert_f32_biteq {
@@ -22,17 +22,9 @@ fn test_powf() {
2222
let inf: f32 = f32::INFINITY;
2323
let neg_inf: f32 = f32::NEG_INFINITY;
2424
assert_eq!(1.0f32.powf(1.0), 1.0);
25-
assert_approx_eq!(
26-
3.4f32.powf(4.5),
27-
246.408218,
28-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
29-
);
25+
assert_approx_eq!(3.4f32.powf(4.5), 246.408218, APPROX_DELTA);
3026
assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
31-
assert_approx_eq!(
32-
(-3.1f32).powf(2.0),
33-
9.61,
34-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
35-
);
27+
assert_approx_eq!((-3.1f32).powf(2.0), 9.61, APPROX_DELTA);
3628
assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
3729
assert_eq!(8.3f32.powf(0.0), 1.0);
3830
assert!(nan.powf(2.0).is_nan());
@@ -44,11 +36,7 @@ fn test_powf() {
4436
fn test_exp() {
4537
assert_eq!(1.0, 0.0f32.exp());
4638
assert_approx_eq!(2.718282, 1.0f32.exp(), APPROX_DELTA);
47-
assert_approx_eq!(
48-
148.413162,
49-
5.0f32.exp(),
50-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
51-
);
39+
assert_approx_eq!(148.413162, 5.0f32.exp(), APPROX_DELTA);
5240

5341
let inf: f32 = f32::INFINITY;
5442
let neg_inf: f32 = f32::NEG_INFINITY;
@@ -60,11 +48,7 @@ fn test_exp() {
6048

6149
#[test]
6250
fn test_exp2() {
63-
assert_approx_eq!(
64-
32.0,
65-
5.0f32.exp2(),
66-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
67-
);
51+
assert_approx_eq!(32.0, 5.0f32.exp2(), APPROX_DELTA);
6852
assert_eq!(1.0, 0.0f32.exp2());
6953

7054
let inf: f32 = f32::INFINITY;
@@ -87,11 +71,7 @@ fn test_ln() {
8771
assert!((-2.3f32).ln().is_nan());
8872
assert_eq!((-0.0f32).ln(), neg_inf);
8973
assert_eq!(0.0f32.ln(), neg_inf);
90-
assert_approx_eq!(
91-
4.0f32.ln(),
92-
1.386294,
93-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
94-
);
74+
assert_approx_eq!(4.0f32.ln(), 1.386294, APPROX_DELTA);
9575
}
9676

9777
#[test]
@@ -101,7 +81,7 @@ fn test_log() {
10181
let neg_inf: f32 = f32::NEG_INFINITY;
10282
assert_approx_eq!(10.0f32.log(10.0), 1.0);
10383
assert_approx_eq!(2.3f32.log(3.5), 0.664858);
104-
assert_approx_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
84+
assert_approx_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0, APPROX_DELTA);
10585
assert!(1.0f32.log(1.0).is_nan());
10686
assert!(1.0f32.log(-13.9).is_nan());
10787
assert!(nan.log(2.3).is_nan());
@@ -117,17 +97,9 @@ fn test_log2() {
11797
let nan: f32 = f32::NAN;
11898
let inf: f32 = f32::INFINITY;
11999
let neg_inf: f32 = f32::NEG_INFINITY;
120-
assert_approx_eq!(
121-
10.0f32.log2(),
122-
3.321928,
123-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
124-
);
100+
assert_approx_eq!(10.0f32.log2(), 3.321928, APPROX_DELTA);
125101
assert_approx_eq!(2.3f32.log2(), 1.201634);
126-
assert_approx_eq!(
127-
1.0f32.exp().log2(),
128-
1.442695,
129-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
130-
);
102+
assert_approx_eq!(1.0f32.exp().log2(), 1.442695, APPROX_DELTA);
131103
assert!(nan.log2().is_nan());
132104
assert_eq!(inf.log2(), inf);
133105
assert!(neg_inf.log2().is_nan());
@@ -191,11 +163,7 @@ fn test_acosh() {
191163
assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
192164

193165
// test for low accuracy from issue 104548
194-
assert_approx_eq!(
195-
60.0f32,
196-
60.0f32.cosh().acosh(),
197-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
198-
);
166+
assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh(), APPROX_DELTA);
199167
}
200168

201169
#[test]
@@ -274,11 +242,7 @@ fn test_real_consts() {
274242
let ln_10: f32 = consts::LN_10;
275243

276244
assert_approx_eq!(frac_pi_2, pi / 2f32);
277-
assert_approx_eq!(
278-
frac_pi_3,
279-
pi / 3f32,
280-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
281-
);
245+
assert_approx_eq!(frac_pi_3, pi / 3f32, APPROX_DELTA);
282246
assert_approx_eq!(frac_pi_4, pi / 4f32);
283247
assert_approx_eq!(frac_pi_6, pi / 6f32);
284248
assert_approx_eq!(frac_pi_8, pi / 8f32);
@@ -290,9 +254,5 @@ fn test_real_consts() {
290254
assert_approx_eq!(log2_e, e.log2());
291255
assert_approx_eq!(log10_e, e.log10());
292256
assert_approx_eq!(ln_2, 2f32.ln());
293-
assert_approx_eq!(
294-
ln_10,
295-
10f32.ln(),
296-
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
297-
);
257+
assert_approx_eq!(ln_10, 10f32.ln(), APPROX_DELTA);
298258
}

src/tools/miri/tests/pass/float.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,7 @@ pub fn libm() {
10341034
assert_approx_eq!(400f64.powf(0.5f64), 20f64);
10351035

10361036
// Some inputs to powf and powi result in fixed outputs
1037-
// and thus must be exactly equal to that value
1037+
// and thus must be exactly equal to that value.
10381038
// C standard says:
10391039
// 1^y = 1 for any y, even a NaN.
10401040
assert_eq!(1f32.powf(10.0), 1.0);
@@ -1069,11 +1069,13 @@ pub fn libm() {
10691069

10701070
// For pow (powf in rust) the C standard says:
10711071
// x^0 = 1 for all x even a sNaN
1072+
// FIXME(#4286): this does not match the behavior of all implementations.
10721073
assert_eq!(SNAN_F32.powf(0.0), 1.0);
10731074
assert_eq!(SNAN_F64.powf(0.0), 1.0);
10741075

10751076
// For pown (powi in rust) the C standard says:
10761077
// x^0 = 1 for all x even a sNaN
1078+
// FIXME(#4286): this does not match the behavior of all implementations.
10771079
assert_eq!(SNAN_F32.powi(0), 1.0);
10781080
assert_eq!(SNAN_F64.powi(0), 1.0);
10791081

0 commit comments

Comments
 (0)