Skip to content

Commit 691f37a

Browse files
fixup! feat(const_eval): impl. round
1 parent 5a74508 commit 691f37a

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

naga/src/proc/constant_evaluator.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,30 @@ impl<'a> ConstantEvaluator<'a> {
834834
component_wise_float!(self, span, [arg], |e| { Ok(e.cosh().into()) })
835835
}
836836
crate::MathFunction::Round => {
837-
component_wise_float!(self, span, [arg], |e| { Ok(e.round().into()) })
837+
// TODO: Use `f{32,64}.round_ties_even()` when available on stable. This polyfill
838+
// is shamelessly [~~stolen from~~ inspired by `ndarray-image`][polyfill source],
839+
// which has licensing compatible with ours. See also
840+
// <https://github.com/rust-lang/rust/issues/96710>.
841+
//
842+
// [polyfill source]: https://github.com/imeka/ndarray-ndimage/blob/8b14b4d6ecfbc96a8a052f802e342a7049c68d8f/src/lib.rs#L98
843+
fn round_ties_even(x: f64) -> f64 {
844+
let i = x as i64;
845+
let f = (x - i as f64).abs();
846+
if f == 0.5 {
847+
if i & 1 == 1 {
848+
// -1.5, 1.5, 3.5, ...
849+
(x.abs() + 0.5).copysign(x)
850+
} else {
851+
(x.abs() - 0.5).copysign(x)
852+
}
853+
} else {
854+
x.round()
855+
}
856+
}
857+
component_wise_float(self, span, [arg], |e| match e {
858+
Float::Abstract([e]) => Ok(round_ties_even(e).into()),
859+
Float::F32([e]) => Ok((round_ties_even(e as f64) as f32).into()),
860+
})
838861
}
839862
crate::MathFunction::Saturate => {
840863
component_wise_float!(self, span, [arg], |e| { Ok(e.clamp(0., 1.).into()) })

0 commit comments

Comments
 (0)