Fix rounding in f32.nearest / f64.nearest
This commit is contained in:
parent
0f42e16446
commit
6dbdefc858
|
@ -561,7 +561,28 @@ pub fn const_eval(
|
||||||
Some(ConstVal::F32(f32::from_bits(*a).trunc().to_bits()))
|
Some(ConstVal::F32(f32::from_bits(*a).trunc().to_bits()))
|
||||||
}
|
}
|
||||||
(Operator::F32Nearest, [ConstVal::F32(a)]) => {
|
(Operator::F32Nearest, [ConstVal::F32(a)]) => {
|
||||||
Some(ConstVal::F32(f32::from_bits(*a).round().to_bits()))
|
// See
|
||||||
|
// https://github.com/paritytech/wasmi/blob/43ce25d47e26498b9372369345e75dc9632eca8f/crates/core/src/value.rs#L662
|
||||||
|
// for the origin of this algorithm.
|
||||||
|
//
|
||||||
|
// When https://github.com/rust-lang/rust/pull/95317 is
|
||||||
|
// resolved and the resulting API is stable, we can switch
|
||||||
|
// to that instead.
|
||||||
|
let a = f32::from_bits(*a);
|
||||||
|
let round = a.round();
|
||||||
|
let nearest = if a.fract().abs() != 0.5 {
|
||||||
|
round
|
||||||
|
} else {
|
||||||
|
let rem = round % 2.0;
|
||||||
|
if rem == 1.0 {
|
||||||
|
a.floor()
|
||||||
|
} else if rem == -1.0 {
|
||||||
|
a.ceil()
|
||||||
|
} else {
|
||||||
|
round
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(ConstVal::F32(nearest.to_bits()))
|
||||||
}
|
}
|
||||||
(Operator::F32Sqrt, [ConstVal::F32(a)]) => {
|
(Operator::F32Sqrt, [ConstVal::F32(a)]) => {
|
||||||
Some(ConstVal::F32(f32::from_bits(*a).sqrt().to_bits()))
|
Some(ConstVal::F32(f32::from_bits(*a).sqrt().to_bits()))
|
||||||
|
@ -604,7 +625,21 @@ pub fn const_eval(
|
||||||
Some(ConstVal::F64(f64::from_bits(*a).trunc().to_bits()))
|
Some(ConstVal::F64(f64::from_bits(*a).trunc().to_bits()))
|
||||||
}
|
}
|
||||||
(Operator::F64Nearest, [ConstVal::F64(a)]) => {
|
(Operator::F64Nearest, [ConstVal::F64(a)]) => {
|
||||||
Some(ConstVal::F64(f64::from_bits(*a).round().to_bits()))
|
let a = f64::from_bits(*a);
|
||||||
|
let round = a.round();
|
||||||
|
let nearest = if a.fract().abs() != 0.5 {
|
||||||
|
round
|
||||||
|
} else {
|
||||||
|
let rem = round % 2.0;
|
||||||
|
if rem == 1.0 {
|
||||||
|
a.floor()
|
||||||
|
} else if rem == -1.0 {
|
||||||
|
a.ceil()
|
||||||
|
} else {
|
||||||
|
round
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Some(ConstVal::F64(nearest.to_bits()))
|
||||||
}
|
}
|
||||||
(Operator::F64Sqrt, [ConstVal::F64(a)]) => {
|
(Operator::F64Sqrt, [ConstVal::F64(a)]) => {
|
||||||
Some(ConstVal::F64(f64::from_bits(*a).sqrt().to_bits()))
|
Some(ConstVal::F64(f64::from_bits(*a).sqrt().to_bits()))
|
||||||
|
|
Loading…
Reference in a new issue