@@ -1171,46 +1171,34 @@ impl<'a> ConstantEvaluator<'a> {
11711171 component_wise_float ! ( self , span, [ arg] , |e| { Ok ( [ e. floor( ) ] ) } )
11721172 }
11731173 crate :: MathFunction :: Round => {
1174- /// Rounds to the nearest integer, with ties biasing towards an even result.
1175- ///
1176- /// # TODO
1177- ///
1178- /// - `round_ties_even` is not available on `half::f16` yet.
1179- /// - It is also not available on `no_std`
1180- ///
1181- /// This polyfill is shamelessly [~~stolen from~~ inspired by `ndarray-image`][polyfill source],
1182- /// which has licensing compatible with ours. See also
1183- /// <https://github.com/rust-lang/rust/issues/96710>.
1184- ///
1185- /// [polyfill source]: https://github.com/imeka/ndarray-ndimage/blob/8b14b4d6ecfbc96a8a052f802e342a7049c68d8f/src/lib.rs#L98
1186- fn round_ties_even < T : num_traits:: float:: FloatCore > ( x : T ) -> T {
1187- let half = ( T :: one ( ) + T :: one ( ) ) . recip ( ) ;
1188-
1189- if x. fract ( ) . abs ( ) != half {
1190- x. round ( )
1191- } else {
1192- let i = x. abs ( ) . trunc ( ) ;
1193-
1194- let value = if ( i * half) . fract ( ) == half {
1195- // -1.5, 1.5, 3.5, ...
1196- x. abs ( ) + half
1197- } else {
1198- // -0.5, 0.5, 2.5, ...
1199- x. abs ( ) - half
1200- } ;
1201-
1202- if x. signum ( ) != value. signum ( ) {
1203- -value
1204- } else {
1205- value
1174+ component_wise_float ( self , span, [ arg] , |e| match e {
1175+ Float :: Abstract ( [ e] ) => Ok ( Float :: Abstract ( [ libm:: rint ( e) ] ) ) ,
1176+ Float :: F32 ( [ e] ) => Ok ( Float :: F32 ( [ libm:: rintf ( e) ] ) ) ,
1177+ Float :: F16 ( [ e] ) => {
1178+ // TODO: `round_ties_even` is not available on `half::f16` yet.
1179+ //
1180+ // This polyfill is shamelessly [~~stolen from~~ inspired by `ndarray-image`][polyfill source],
1181+ // which has licensing compatible with ours. See also
1182+ // <https://github.com/rust-lang/rust/issues/96710>.
1183+ //
1184+ // [polyfill source]: https://github.com/imeka/ndarray-ndimage/blob/8b14b4d6ecfbc96a8a052f802e342a7049c68d8f/src/lib.rs#L98
1185+ fn round_ties_even ( x : f64 ) -> f64 {
1186+ let i = x as i64 ;
1187+ let f = ( x - i as f64 ) . abs ( ) ;
1188+ if f == 0.5 {
1189+ if i & 1 == 1 {
1190+ // -1.5, 1.5, 3.5, ...
1191+ ( x. abs ( ) + 0.5 ) . copysign ( x)
1192+ } else {
1193+ ( x. abs ( ) - 0.5 ) . copysign ( x)
1194+ }
1195+ } else {
1196+ x. round ( )
1197+ }
12061198 }
1207- }
1208- }
12091199
1210- component_wise_float ( self , span, [ arg] , |e| match e {
1211- Float :: Abstract ( [ e] ) => Ok ( Float :: Abstract ( [ round_ties_even ( e) ] ) ) ,
1212- Float :: F32 ( [ e] ) => Ok ( Float :: F32 ( [ round_ties_even ( e) ] ) ) ,
1213- Float :: F16 ( [ e] ) => Ok ( Float :: F16 ( [ round_ties_even ( e) ] ) ) ,
1200+ Ok ( Float :: F16 ( [ ( f16:: from_f64 ( round_ties_even ( f64:: from ( e) ) ) ) ] ) )
1201+ }
12141202 } )
12151203 }
12161204 crate :: MathFunction :: Fract => {
0 commit comments