@@ -31,6 +31,7 @@ fn main() {
3131 test_fast ( ) ;
3232 test_algebraic ( ) ;
3333 test_fmuladd ( ) ;
34+ test_min_max_nondet ( ) ;
3435}
3536
3637trait Float : Copy + PartialEq + Debug {
@@ -1211,3 +1212,30 @@ fn test_fmuladd() {
12111212 test_operations_f32 ( 0.1 , 0.2 , 0.3 ) ;
12121213 test_operations_f64 ( 1.1 , 1.2 , 1.3 ) ;
12131214}
1215+
1216+ /// `min` and `max` on equal arguments are non-deterministic.
1217+ fn test_min_max_nondet ( ) {
1218+ /// Ensure that if we call the closure often enough, we see both `true` and `false.`
1219+ #[ track_caller]
1220+ fn ensure_both ( f : impl Fn ( ) -> bool ) {
1221+ let rounds = 16 ;
1222+ let first = f ( ) ;
1223+ for _ in 1 ..rounds {
1224+ if f ( ) != first {
1225+ // We saw two different values!
1226+ return ;
1227+ }
1228+ }
1229+ // We saw the same thing N times.
1230+ panic ! ( "expected non-determinism, got {rounds} times the same result: {first:?}" ) ;
1231+ }
1232+
1233+ ensure_both ( || f16:: min ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1234+ ensure_both ( || f16:: max ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1235+ ensure_both ( || f32:: min ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1236+ ensure_both ( || f32:: max ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1237+ ensure_both ( || f64:: min ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1238+ ensure_both ( || f64:: max ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1239+ ensure_both ( || f128:: min ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1240+ ensure_both ( || f128:: max ( 0.0 , -0.0 ) . is_sign_positive ( ) ) ;
1241+ }
0 commit comments