core: Improve performance of round_to_even
This patch improves performance of ecma_conversions::round_to_even(): 1. by using f64::round_ties_even(), which has been stable since 1.77.0, instead of a custom algorithm; and 2. by removing an unnecessary comparison to i32::MIN, as casting a float to an integer automatically saturates values smaller than the minimum integer value to the minimum value of the integer type.
This commit is contained in:
parent
8eaf844cdc
commit
bc4ed4c5a1
|
@ -45,17 +45,11 @@ pub fn f64_to_wrapping_i32(n: f64) -> i32 {
|
||||||
|
|
||||||
/// Implements the IEEE-754 "Round to nearest, ties to even" rounding rule.
|
/// Implements the IEEE-754 "Round to nearest, ties to even" rounding rule.
|
||||||
/// (e.g., both 1.5 and 2.5 will round to 2).
|
/// (e.g., both 1.5 and 2.5 will round to 2).
|
||||||
/// Although this is easy to do on most architectures, Rust provides no standard
|
|
||||||
/// way to round in this manner (`f64::round` always rounds away from zero).
|
|
||||||
/// For more info and the below code snippet, see: https://github.com/rust-lang/rust/issues/55107
|
|
||||||
/// This also clamps out-of-range values and NaN to `i32::MIN`.
|
/// This also clamps out-of-range values and NaN to `i32::MIN`.
|
||||||
/// TODO: Investigate using SSE/wasm intrinsics for this.
|
|
||||||
pub fn round_to_even(n: f64) -> i32 {
|
pub fn round_to_even(n: f64) -> i32 {
|
||||||
let k = 1.0 / f64::EPSILON;
|
let out = n.round_ties_even();
|
||||||
let a = n.abs();
|
|
||||||
let out = if a < k { ((a + k) - k).copysign(n) } else { n };
|
|
||||||
// Clamp out-of-range values to `i32::MIN`.
|
// Clamp out-of-range values to `i32::MIN`.
|
||||||
if out.is_finite() && out >= i32::MIN.into() && out <= i32::MAX.into() {
|
if out.is_finite() && out <= i32::MAX.into() {
|
||||||
out as i32
|
out as i32
|
||||||
} else {
|
} else {
|
||||||
i32::MIN
|
i32::MIN
|
||||||
|
|
Loading…
Reference in New Issue