@@ -46,7 +46,7 @@ pub fn ceil_status<F: Float>(x: F) -> FpResult<F> {
4646 F :: from_bits ( ix)
4747 } else {
4848 // |x| < 1.0, raise an inexact exception since truncation will happen (unless x == 0).
49- if ix & F :: SIG_MASK == F :: Int :: ZERO {
49+ if ix & ! F :: SIGN_MASK == F :: Int :: ZERO {
5050 status = Status :: OK ;
5151 } else {
5252 status = Status :: INEXACT ;
@@ -72,103 +72,83 @@ mod tests {
7272 use super :: * ;
7373 use crate :: support:: Hexf ;
7474
75- /// Test against https://en.cppreference.com/w/cpp/numeric/math/ceil
76- fn spec_test < F : Float > ( cases : & [ ( F , F , Status ) ] ) {
77- let roundtrip = [
78- F :: ZERO ,
79- F :: ONE ,
80- F :: NEG_ONE ,
81- F :: NEG_ZERO ,
82- F :: INFINITY ,
83- F :: NEG_INFINITY ,
84- ] ;
85-
86- for x in roundtrip {
87- let FpResult { val, status } = ceil_status ( x) ;
88- assert_biteq ! ( val, x, "{}" , Hexf ( x) ) ;
89- assert_eq ! ( status, Status :: OK , "{}" , Hexf ( x) ) ;
90- }
75+ macro_rules! cases {
76+ ( $f: ty) => {
77+ [
78+ // roundtrip
79+ ( 0.0 , 0.0 , Status :: OK ) ,
80+ ( -0.0 , -0.0 , Status :: OK ) ,
81+ ( 1.0 , 1.0 , Status :: OK ) ,
82+ ( -1.0 , -1.0 , Status :: OK ) ,
83+ ( <$f>:: INFINITY , <$f>:: INFINITY , Status :: OK ) ,
84+ ( <$f>:: NEG_INFINITY , <$f>:: NEG_INFINITY , Status :: OK ) ,
85+ // with rounding
86+ ( 0.1 , 1.0 , Status :: INEXACT ) ,
87+ ( -0.1 , -0.0 , Status :: INEXACT ) ,
88+ ( 0.5 , 1.0 , Status :: INEXACT ) ,
89+ ( -0.5 , -0.0 , Status :: INEXACT ) ,
90+ ( 0.9 , 1.0 , Status :: INEXACT ) ,
91+ ( -0.9 , -0.0 , Status :: INEXACT ) ,
92+ ( 1.1 , 2.0 , Status :: INEXACT ) ,
93+ ( -1.1 , -1.0 , Status :: INEXACT ) ,
94+ ( 1.5 , 2.0 , Status :: INEXACT ) ,
95+ ( -1.5 , -1.0 , Status :: INEXACT ) ,
96+ ( 1.9 , 2.0 , Status :: INEXACT ) ,
97+ ( -1.9 , -1.0 , Status :: INEXACT ) ,
98+ ]
99+ } ;
100+ }
91101
92- for & ( x, res, res_stat) in cases {
102+ #[ track_caller]
103+ fn check < F : Float > ( cases : & [ ( F , F , Status ) ] ) {
104+ for & ( x, exp_res, exp_stat) in cases {
93105 let FpResult { val, status } = ceil_status ( x) ;
94- assert_biteq ! ( val, res, "{}" , Hexf ( x) ) ;
95- assert_eq ! ( status, res_stat, "{}" , Hexf ( x) ) ;
106+ assert_biteq ! ( val, exp_res, "{x:?} {}" , Hexf ( x) ) ;
107+ assert_eq ! (
108+ status,
109+ exp_stat,
110+ "{x:?} {} -> {exp_res:?} {}" ,
111+ Hexf ( x) ,
112+ Hexf ( exp_res)
113+ ) ;
96114 }
97115 }
98116
99- /* Skipping f16 / f128 "sanity_check"s due to rejected literal lexing at MSRV */
100-
101117 #[ test]
102118 #[ cfg( f16_enabled) ]
103- fn spec_tests_f16 ( ) {
104- let cases = [
105- ( 0.1 , 1.0 , Status :: INEXACT ) ,
106- ( -0.1 , -0.0 , Status :: INEXACT ) ,
107- ( 0.9 , 1.0 , Status :: INEXACT ) ,
108- ( -0.9 , -0.0 , Status :: INEXACT ) ,
109- ( 1.1 , 2.0 , Status :: INEXACT ) ,
110- ( -1.1 , -1.0 , Status :: INEXACT ) ,
111- ( 1.9 , 2.0 , Status :: INEXACT ) ,
112- ( -1.9 , -1.0 , Status :: INEXACT ) ,
113- ] ;
114- spec_test :: < f16 > ( & cases) ;
115- }
116-
117- #[ test]
118- fn sanity_check_f32 ( ) {
119- assert_eq ! ( ceil( 1.1f32 ) , 2.0 ) ;
120- assert_eq ! ( ceil( 2.9f32 ) , 3.0 ) ;
121- }
122-
123- #[ test]
124- fn spec_tests_f32 ( ) {
125- let cases = [
126- ( 0.1 , 1.0 , Status :: INEXACT ) ,
127- ( -0.1 , -0.0 , Status :: INEXACT ) ,
128- ( 0.9 , 1.0 , Status :: INEXACT ) ,
129- ( -0.9 , -0.0 , Status :: INEXACT ) ,
130- ( 1.1 , 2.0 , Status :: INEXACT ) ,
131- ( -1.1 , -1.0 , Status :: INEXACT ) ,
132- ( 1.9 , 2.0 , Status :: INEXACT ) ,
133- ( -1.9 , -1.0 , Status :: INEXACT ) ,
134- ] ;
135- spec_test :: < f32 > ( & cases) ;
119+ fn check_f16 ( ) {
120+ check :: < f16 > ( & cases ! ( f16) ) ;
121+ check :: < f16 > ( & [
122+ ( hf16 ! ( "0x1p10" ) , hf16 ! ( "0x1p10" ) , Status :: OK ) ,
123+ ( hf16 ! ( "-0x1p10" ) , hf16 ! ( "-0x1p10" ) , Status :: OK ) ,
124+ ] ) ;
136125 }
137126
138127 #[ test]
139- fn sanity_check_f64 ( ) {
140- assert_eq ! ( ceil( 1.1f64 ) , 2.0 ) ;
141- assert_eq ! ( ceil( 2.9f64 ) , 3.0 ) ;
128+ fn check_f32 ( ) {
129+ check :: < f32 > ( & cases ! ( f32 ) ) ;
130+ check :: < f32 > ( & [
131+ ( hf32 ! ( "0x1p23" ) , hf32 ! ( "0x1p23" ) , Status :: OK ) ,
132+ ( hf32 ! ( "-0x1p23" ) , hf32 ! ( "-0x1p23" ) , Status :: OK ) ,
133+ ] ) ;
142134 }
143135
144136 #[ test]
145- fn spec_tests_f64 ( ) {
146- let cases = [
147- ( 0.1 , 1.0 , Status :: INEXACT ) ,
148- ( -0.1 , -0.0 , Status :: INEXACT ) ,
149- ( 0.9 , 1.0 , Status :: INEXACT ) ,
150- ( -0.9 , -0.0 , Status :: INEXACT ) ,
151- ( 1.1 , 2.0 , Status :: INEXACT ) ,
152- ( -1.1 , -1.0 , Status :: INEXACT ) ,
153- ( 1.9 , 2.0 , Status :: INEXACT ) ,
154- ( -1.9 , -1.0 , Status :: INEXACT ) ,
155- ] ;
156- spec_test :: < f64 > ( & cases) ;
137+ fn check_f64 ( ) {
138+ check :: < f64 > ( & cases ! ( f64 ) ) ;
139+ check :: < f64 > ( & [
140+ ( hf64 ! ( "0x1p52" ) , hf64 ! ( "0x1p52" ) , Status :: OK ) ,
141+ ( hf64 ! ( "-0x1p52" ) , hf64 ! ( "-0x1p52" ) , Status :: OK ) ,
142+ ] ) ;
157143 }
158144
159145 #[ test]
160146 #[ cfg( f128_enabled) ]
161147 fn spec_tests_f128 ( ) {
162- let cases = [
163- ( 0.1 , 1.0 , Status :: INEXACT ) ,
164- ( -0.1 , -0.0 , Status :: INEXACT ) ,
165- ( 0.9 , 1.0 , Status :: INEXACT ) ,
166- ( -0.9 , -0.0 , Status :: INEXACT ) ,
167- ( 1.1 , 2.0 , Status :: INEXACT ) ,
168- ( -1.1 , -1.0 , Status :: INEXACT ) ,
169- ( 1.9 , 2.0 , Status :: INEXACT ) ,
170- ( -1.9 , -1.0 , Status :: INEXACT ) ,
171- ] ;
172- spec_test :: < f128 > ( & cases) ;
148+ check :: < f128 > ( & cases ! ( f128) ) ;
149+ check :: < f128 > ( & [
150+ ( hf128 ! ( "0x1p112" ) , hf128 ! ( "0x1p112" ) , Status :: OK ) ,
151+ ( hf128 ! ( "-0x1p112" ) , hf128 ! ( "-0x1p112" ) , Status :: OK ) ,
152+ ] ) ;
173153 }
174154}
0 commit comments