[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:18:02 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: sriramshastry
<details>
<summary>Changes</summary>
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
---
Full diff: https://github.com/llvm/llvm-project/pull/221648.diff
1 Files Affected:
- (modified) libc/src/__support/FPUtil/NearestIntegerOperations.h (+25)
``````````diff
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;
``````````
</details>
https://github.com/llvm/llvm-project/pull/221648
More information about the libc-commits
mailing list