cranelift: Use round_ties_even for nearest in interpreter (#4413)
As @MaxGraey pointed out (thanks!) in #4397, `round` has different behavior from `nearest`. And it looks like the native rust implementation is still pending stabilization. Right now we duplicate the wasmtime implementation, merged in #2171. However, we definitely should switch to the rust native version when it is available.
This commit is contained in:
@@ -816,9 +816,20 @@ impl Ieee32 {
|
||||
Self::with_float(self.as_f32().trunc())
|
||||
}
|
||||
|
||||
/// Returns the nearest integer to `self`. Round half-way cases away from `0.0`.
|
||||
pub fn nearest(self) -> Self {
|
||||
Self::with_float(self.as_f32().round())
|
||||
/// Returns the nearest integer to `self`. Rounds half-way cases to the number
|
||||
/// with an even least significant digit.
|
||||
pub fn round_ties_even(self) -> Self {
|
||||
// TODO: Replace with the native implementation once
|
||||
// https://github.com/rust-lang/rust/issues/96710 is stabilized
|
||||
let toint_32: f32 = 1.0 / f32::EPSILON;
|
||||
|
||||
let f = self.as_f32();
|
||||
let e = self.0 >> 23 & 0xff;
|
||||
if e >= 0x7f_u32 + 23 {
|
||||
self
|
||||
} else {
|
||||
Self::with_float((f.abs() + toint_32 - toint_32).copysign(f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,9 +976,20 @@ impl Ieee64 {
|
||||
Self::with_float(self.as_f64().trunc())
|
||||
}
|
||||
|
||||
/// Returns the nearest integer to `self`. Round half-way cases away from `0.0`.
|
||||
pub fn nearest(self) -> Self {
|
||||
Self::with_float(self.as_f64().round())
|
||||
/// Returns the nearest integer to `self`. Rounds half-way cases to the number
|
||||
/// with an even least significant digit.
|
||||
pub fn round_ties_even(self) -> Self {
|
||||
// TODO: Replace with the native implementation once
|
||||
// https://github.com/rust-lang/rust/issues/96710 is stabilized
|
||||
let toint_64: f64 = 1.0 / f64::EPSILON;
|
||||
|
||||
let f = self.as_f64();
|
||||
let e = self.0 >> 52 & 0x7ff_u64;
|
||||
if e >= 0x3ff_u64 + 52 {
|
||||
self
|
||||
} else {
|
||||
Self::with_float((f.abs() + toint_64 - toint_64).copysign(f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user