Description
C has three reasonably similar ways to round a single float to even. I'll just copy the docs here, nearbyint
:
Description
The
nearbyint
functions round their argument to an integer value in floating-point format, using the current rounding direction and without raising the "inexact" floating-point exception.Returns
The
nearbyint
functions return the rounded integer value.
rint
:
Description
The rint functions differ from the nearbyint functions (7.12.9.3) only in that the rint functions may raise the "inexact" floating-point exception if the result differs in value from the argument
Returns
The rint functions return the rounded integer value.
And roundeven
, which is available since C23:
Description
The roundeven functions round their argument to the nearest integer value in floating-point format, rounding halfway cases to even (that is, to the nearest value that is an even integer), regardless of the current rounding direction
Returns
The round functions return the rounded integer value.
We currently use rintf16
, rintf32
, rintf64
, and rintf128
(e.g. https://doc.rust-lang.org/std/intrinsics/fn.rintf32.html) as the intrinsics to implement round_ties_even
. These map to LLVM's rint
and similar:
rust/compiler/rustc_codegen_llvm/src/intrinsic.rs
Lines 129 to 132 in 613bdd4
rint
is not exactly what we want here because it is supposed to raise inexact. We should change to roundeven
because it matches Rust's preference of ignoring rounding modes and never raising fp exceptions.
This may be blocked on platform support, e.g. llvm/llvm-project#73588. that issue looks like it is about the vector version.
Cc #55107.