Skip to content

Commit 6177235

Browse files
Enable Float non-determinism in miri. Update and add tests and change
change tests in std, core and coretests.
1 parent 6de3a73 commit 6177235

File tree

9 files changed

+413
-101
lines changed

9 files changed

+413
-101
lines changed

library/coretests/tests/floats/f64.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ fn test_powi() {
422422
let nan: f64 = f64::NAN;
423423
let inf: f64 = f64::INFINITY;
424424
let neg_inf: f64 = f64::NEG_INFINITY;
425-
assert_biteq!(1.0f64.powi(1), 1.0);
425+
assert_approx_eq!(1.0f64.powi(1), 1.0);
426426
assert_approx_eq!((-3.1f64).powi(2), 9.61);
427427
assert_approx_eq!(5.9f64.powi(-2), 0.028727);
428428
assert_biteq!(8.3f64.powi(0), 1.0);

library/coretests/tests/num/dec2flt/float.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ fn test_f16_integer_decode() {
2323
fn test_f32_integer_decode() {
2424
assert_eq!(3.14159265359f32.integer_decode(), (13176795, -22, 1));
2525
assert_eq!((-8573.5918555f32).integer_decode(), (8779358, -10, -1));
26-
assert_eq!(2f32.powf(100.0).integer_decode(), (8388608, 77, 1));
26+
// Set 2^100 directly instead of using powf, because it doesn't guarentee precision
27+
assert_eq!(1.2676506e30_f32.integer_decode(), (8388608, 77, 1));
2728
assert_eq!(0f32.integer_decode(), (0, -150, 1));
2829
assert_eq!((-0f32).integer_decode(), (0, -150, -1));
2930
assert_eq!(f32::INFINITY.integer_decode(), (8388608, 105, 1));
@@ -39,7 +40,8 @@ fn test_f32_integer_decode() {
3940
fn test_f64_integer_decode() {
4041
assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906, -51, 1));
4142
assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931, -39, -1));
42-
assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496, 48, 1));
43+
// Set 2^100 directly instead of using powf, because it doesn't guarentee precision
44+
assert_eq!(1.2676506002282294e30_f64.integer_decode(), (4503599627370496, 48, 1));
4345
assert_eq!(0f64.integer_decode(), (0, -1075, 1));
4446
assert_eq!((-0f64).integer_decode(), (0, -1075, -1));
4547
assert_eq!(f64::INFINITY.integer_decode(), (4503599627370496, 972, 1));

library/std/src/num/f32.rs

Lines changed: 16 additions & 16 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 <= f32::EPSILON);
301+
/// assert!(abs_difference <= 8.0 * f32::EPSILON);
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 <= f32::EPSILON);
325+
/// assert!(abs_difference <= 8.0 * f32::EPSILON);
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 <= f32::EPSILON);
385+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
410+
/// assert!(abs_difference <= 8.0 * f32::EPSILON);
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 <= f32::EPSILON);
439+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
476+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
509+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
542+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
649+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
673+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
697+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
698698
/// ```
699699
#[rustc_allow_incoherent_impl]
700700
#[must_use = "method returns a new number and does not mutate the original value"]
@@ -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 <= f32::EPSILON);
781+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
882-
/// assert!(abs_difference_1 <= f32::EPSILON);
881+
/// assert!(abs_difference_0 <= 4.0 * f32::EPSILON);
882+
/// assert!(abs_difference_1 <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
1064+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f32::EPSILON);
1092+
/// assert!(abs_difference <= 4.0 * f32::EPSILON);
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 <= f64::EPSILON);
301+
/// assert!(abs_difference <= 8.0 * f64::EPSILON);
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 <= f64::EPSILON);
325+
/// assert!(abs_difference <= 8.0 * f64::EPSILON);
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: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
use std::f32::consts;
22

3+
/// Miri adds some extra errors to float functions; make sure the tests still pass.
4+
/// These values are purely used as a canary to test against and are thus not a stable guarantee Rust provides.
5+
/// 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 };
7+
38
#[allow(unused_macros)]
49
macro_rules! assert_f32_biteq {
510
($left : expr, $right : expr) => {
@@ -17,9 +22,17 @@ fn test_powf() {
1722
let inf: f32 = f32::INFINITY;
1823
let neg_inf: f32 = f32::NEG_INFINITY;
1924
assert_eq!(1.0f32.powf(1.0), 1.0);
20-
assert_approx_eq!(3.4f32.powf(4.5), 246.408218);
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+
);
2130
assert_approx_eq!(2.7f32.powf(-3.2), 0.041652);
22-
assert_approx_eq!((-3.1f32).powf(2.0), 9.61);
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+
);
2336
assert_approx_eq!(5.9f32.powf(-2.0), 0.028727);
2437
assert_eq!(8.3f32.powf(0.0), 1.0);
2538
assert!(nan.powf(2.0).is_nan());
@@ -30,8 +43,12 @@ fn test_powf() {
3043
#[test]
3144
fn test_exp() {
3245
assert_eq!(1.0, 0.0f32.exp());
33-
assert_approx_eq!(2.718282, 1.0f32.exp());
34-
assert_approx_eq!(148.413162, 5.0f32.exp());
46+
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+
);
3552

3653
let inf: f32 = f32::INFINITY;
3754
let neg_inf: f32 = f32::NEG_INFINITY;
@@ -43,7 +60,11 @@ fn test_exp() {
4360

4461
#[test]
4562
fn test_exp2() {
46-
assert_eq!(32.0, 5.0f32.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+
);
4768
assert_eq!(1.0, 0.0f32.exp2());
4869

4970
let inf: f32 = f32::INFINITY;
@@ -66,17 +87,21 @@ fn test_ln() {
6687
assert!((-2.3f32).ln().is_nan());
6788
assert_eq!((-0.0f32).ln(), neg_inf);
6889
assert_eq!(0.0f32.ln(), neg_inf);
69-
assert_approx_eq!(4.0f32.ln(), 1.386294);
90+
assert_approx_eq!(
91+
4.0f32.ln(),
92+
1.386294,
93+
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
94+
);
7095
}
7196

7297
#[test]
7398
fn test_log() {
7499
let nan: f32 = f32::NAN;
75100
let inf: f32 = f32::INFINITY;
76101
let neg_inf: f32 = f32::NEG_INFINITY;
77-
assert_eq!(10.0f32.log(10.0), 1.0);
102+
assert_approx_eq!(10.0f32.log(10.0), 1.0);
78103
assert_approx_eq!(2.3f32.log(3.5), 0.664858);
79-
assert_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
104+
assert_approx_eq!(1.0f32.exp().log(1.0f32.exp()), 1.0);
80105
assert!(1.0f32.log(1.0).is_nan());
81106
assert!(1.0f32.log(-13.9).is_nan());
82107
assert!(nan.log(2.3).is_nan());
@@ -92,9 +117,17 @@ fn test_log2() {
92117
let nan: f32 = f32::NAN;
93118
let inf: f32 = f32::INFINITY;
94119
let neg_inf: f32 = f32::NEG_INFINITY;
95-
assert_approx_eq!(10.0f32.log2(), 3.321928);
120+
assert_approx_eq!(
121+
10.0f32.log2(),
122+
3.321928,
123+
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
124+
);
96125
assert_approx_eq!(2.3f32.log2(), 1.201634);
97-
assert_approx_eq!(1.0f32.exp().log2(), 1.442695);
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+
);
98131
assert!(nan.log2().is_nan());
99132
assert_eq!(inf.log2(), inf);
100133
assert!(neg_inf.log2().is_nan());
@@ -108,7 +141,7 @@ fn test_log10() {
108141
let nan: f32 = f32::NAN;
109142
let inf: f32 = f32::INFINITY;
110143
let neg_inf: f32 = f32::NEG_INFINITY;
111-
assert_eq!(10.0f32.log10(), 1.0);
144+
assert_approx_eq!(10.0f32.log10(), 1.0);
112145
assert_approx_eq!(2.3f32.log10(), 0.361728);
113146
assert_approx_eq!(1.0f32.exp().log10(), 0.434294);
114147
assert_eq!(1.0f32.log10(), 0.0);
@@ -158,7 +191,11 @@ fn test_acosh() {
158191
assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
159192

160193
// test for low accuracy from issue 104548
161-
assert_approx_eq!(60.0f32, 60.0f32.cosh().acosh());
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+
);
162199
}
163200

164201
#[test]
@@ -237,7 +274,11 @@ fn test_real_consts() {
237274
let ln_10: f32 = consts::LN_10;
238275

239276
assert_approx_eq!(frac_pi_2, pi / 2f32);
240-
assert_approx_eq!(frac_pi_3, pi / 3f32);
277+
assert_approx_eq!(
278+
frac_pi_3,
279+
pi / 3f32,
280+
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
281+
);
241282
assert_approx_eq!(frac_pi_4, pi / 4f32);
242283
assert_approx_eq!(frac_pi_6, pi / 6f32);
243284
assert_approx_eq!(frac_pi_8, pi / 8f32);
@@ -249,5 +290,9 @@ fn test_real_consts() {
249290
assert_approx_eq!(log2_e, e.log2());
250291
assert_approx_eq!(log10_e, e.log10());
251292
assert_approx_eq!(ln_2, 2f32.ln());
252-
assert_approx_eq!(ln_10, 10f32.ln());
293+
assert_approx_eq!(
294+
ln_10,
295+
10f32.ln(),
296+
APPROX_DELTA /* Miri float-non-det: Make tests pass for now */
297+
);
253298
}

library/std/tests/floats/f64.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ fn test_exp() {
4343

4444
#[test]
4545
fn test_exp2() {
46-
assert_eq!(32.0, 5.0f64.exp2());
46+
assert_approx_eq!(32.0, 5.0f64.exp2());
4747
assert_eq!(1.0, 0.0f64.exp2());
4848

4949
let inf: f64 = f64::INFINITY;
@@ -74,9 +74,9 @@ fn test_log() {
7474
let nan: f64 = f64::NAN;
7575
let inf: f64 = f64::INFINITY;
7676
let neg_inf: f64 = f64::NEG_INFINITY;
77-
assert_eq!(10.0f64.log(10.0), 1.0);
77+
assert_approx_eq!(10.0f64.log(10.0), 1.0);
7878
assert_approx_eq!(2.3f64.log(3.5), 0.664858);
79-
assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
79+
assert_approx_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
8080
assert!(1.0f64.log(1.0).is_nan());
8181
assert!(1.0f64.log(-13.9).is_nan());
8282
assert!(nan.log(2.3).is_nan());
@@ -108,7 +108,7 @@ fn test_log10() {
108108
let nan: f64 = f64::NAN;
109109
let inf: f64 = f64::INFINITY;
110110
let neg_inf: f64 = f64::NEG_INFINITY;
111-
assert_eq!(10.0f64.log10(), 1.0);
111+
assert_approx_eq!(10.0f64.log10(), 1.0);
112112
assert_approx_eq!(2.3f64.log10(), 0.361728);
113113
assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
114114
assert_eq!(1.0f64.log10(), 0.0);

0 commit comments

Comments
 (0)