@@ -1171,46 +1171,34 @@ impl<'a> ConstantEvaluator<'a> {
1171
1171
component_wise_float ! ( self , span, [ arg] , |e| { Ok ( [ e. floor( ) ] ) } )
1172
1172
}
1173
1173
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
+ }
1206
1198
}
1207
- }
1208
- }
1209
1199
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
+ }
1214
1202
} )
1215
1203
}
1216
1204
crate :: MathFunction :: Fract => {
0 commit comments