[libc-commits] [libc] [libc][math] Add bit-rounding roundf implementation (PR #221648)
via libc-commits
libc-commits at lists.llvm.org
Sun Sep 6 23:17:07 PDT 2026
https://github.com/sriramshastry created https://github.com/llvm/llvm-project/pull/221648
Add a float-specific fputil::round overload for roundf. It uses FPBits<float> and the biased exponent to handle sub-unit values, already-integral inputs, and finite values with fractional bits.
For finite fractional values, add the rounding bit and clear the lower mask. This implements round-to-nearest with halfway cases away from zero using integer operations on the float encoding.
Tests: libc.test.src.math.smoke.roundf_test
Tests: libc.test.src.math.smoke.roundf_test.__NO_ROUND_OPT
>From 3e971a2659eb5ce656f35620b9b7fbd360b8c918 Mon Sep 17 00:00:00 2001
From: Sriram Shastry <sriramshastry at gmail.com>
Date: Fri, 4 Sep 2026 12:41:21 +0530
Subject: [PATCH] [libc][math] Add bit-rounding roundf implementation
Add a float-specific fputil::round overload for roundf. It uses
FPBits<float> and the biased exponent to handle sub-unit values,
already-integral inputs, and finite values with fractional bits.
For finite fractional values, add the rounding bit and clear the
lower mask. This implements round-to-nearest with halfway cases away
from zero using integer operations on the float encoding.
Tests: libc.test.src.math.smoke.roundf_test
Tests: libc.test.src.math.smoke.roundf_test.__NO_ROUND_OPT
---
.../FPUtil/NearestIntegerOperations.h | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index 203e3c43ae9c9..7e52e8cfb18d6 100644
--- a/libc/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h
@@ -104,6 +104,31 @@ LIBC_INLINE constexpr T floor(T x) {
}
}
+LIBC_INLINE constexpr float round(float x) {
+ using FloatBits = FPBits<float>;
+ using StorageType = typename FloatBits::StorageType;
+
+ FloatBits bits(x);
+ StorageType x_u = bits.uintval();
+ StorageType biased_exponent = bits.get_biased_exponent();
+
+ if (biased_exponent <= FloatBits::EXP_BIAS - 1) {
+ if (biased_exponent == FloatBits::EXP_BIAS - 1)
+ return FloatBits::one(bits.sign()).get_val();
+ return FloatBits::zero(bits.sign()).get_val();
+ }
+
+ if (biased_exponent >= FloatBits::EXP_BIAS + FloatBits::FRACTION_LEN)
+ return x;
+
+ StorageType exponent = biased_exponent - FloatBits::EXP_BIAS;
+ StorageType round_bit = StorageType(1)
+ << (FloatBits::FRACTION_LEN - exponent - 1);
+ StorageType mask = static_cast<StorageType>((round_bit << 1) - 1);
+ return FloatBits(static_cast<StorageType>((x_u + round_bit) & ~mask))
+ .get_val();
+}
+
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE constexpr T round(T x) {
using StorageType = typename FPBits<T>::StorageType;
More information about the libc-commits
mailing list