Rollup merge of #156647 - oscargus:fasterfloatmidpoint, r=SimonSapin

Change division to multiplication in floating-point midpoint

Multiplication is faster than division on most (all?) platforms. While the optimizer will handle this, there is really no point in relying on that. Using multiplication directly will not have any drawbacks and are numerically identical (in this case since 1.0 / 2.0 == 0.5)

Consider the examples at https://godbolt.org/z/oMvb9vobG where it is clear that the non-optimized version uses division, while the optimized version uses multiplication.
This commit is contained in:
Jonathan Brouwer
2026-05-18 03:19:49 +02:00
committed by GitHub
4 changed files with 13 additions and 13 deletions
+3 -3
View File
@@ -977,7 +977,7 @@ pub const fn minimum(self, other: f128) -> f128 {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub const fn midpoint(self, other: f128) -> f128 {
const HI: f128 = f128::MAX / 2.;
const HI: f128 = f128::MAX * 0.5;
let (a, b) = (self, other);
let abs_a = a.abs();
@@ -985,9 +985,9 @@ pub const fn midpoint(self, other: f128) -> f128 {
if abs_a <= HI && abs_b <= HI {
// Overflow is impossible
(a + b) / 2.
(a + b) * 0.5
} else {
(a / 2.) + (b / 2.)
(a * 0.5) + (b * 0.5)
}
}
+3 -3
View File
@@ -973,7 +973,7 @@ pub const fn minimum(self, other: f16) -> f16 {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub const fn midpoint(self, other: f16) -> f16 {
const HI: f16 = f16::MAX / 2.;
const HI: f16 = f16::MAX * 0.5;
let (a, b) = (self, other);
let abs_a = a.abs();
@@ -981,9 +981,9 @@ pub const fn midpoint(self, other: f16) -> f16 {
if abs_a <= HI && abs_b <= HI {
// Overflow is impossible
(a + b) / 2.
(a + b) * 0.5
} else {
(a / 2.) + (b / 2.)
(a * 0.5) + (b * 0.5)
}
}
+4 -4
View File
@@ -1164,10 +1164,10 @@ pub const fn midpoint(self, other: f32) -> f32 {
target_arch = "wasm32",
target_arch = "wasm64",
) => {
((self as f64 + other as f64) / 2.0) as f32
((self as f64 + other as f64) * 0.5) as f32
}
_ => {
const HI: f32 = f32::MAX / 2.;
const HI: f32 = f32::MAX * 0.5;
let (a, b) = (self, other);
let abs_a = a.abs();
@@ -1175,9 +1175,9 @@ pub const fn midpoint(self, other: f32) -> f32 {
if abs_a <= HI && abs_b <= HI {
// Overflow is impossible
(a + b) / 2.
(a + b) * 0.5
} else {
(a / 2.) + (b / 2.)
(a * 0.5) + (b * 0.5)
}
}
}
+3 -3
View File
@@ -1150,7 +1150,7 @@ pub const fn minimum(self, other: f64) -> f64 {
#[must_use = "this returns the result of the operation, \
without modifying the original"]
pub const fn midpoint(self, other: f64) -> f64 {
const HI: f64 = f64::MAX / 2.;
const HI: f64 = f64::MAX * 0.5;
let (a, b) = (self, other);
let abs_a = a.abs();
@@ -1158,9 +1158,9 @@ pub const fn midpoint(self, other: f64) -> f64 {
if abs_a <= HI && abs_b <= HI {
// Overflow is impossible
(a + b) / 2.
(a + b) * 0.5
} else {
(a / 2.) + (b / 2.)
(a * 0.5) + (b * 0.5)
}
}