[libc-commits] [PATCH] D136799: [libc] Implement a high-precision floating point class.

Kirill Okhotnikov via Phabricator via libc-commits libc-commits at lists.llvm.org
Thu Oct 27 11:08:36 PDT 2022


orex added inline comments.


================
Comment at: libc/src/__support/FPUtil/big_float.h:32
+template <size_t MANTISSA_LENGTH> struct BigFloat {
+  static_assert(MANTISSA_LENGTH >= 64 && MANTISSA_LENGTH % 8 == 0,
+                "Unsupported mantissa length.");
----------------
static_assert in UInt is stricter than this one (https://github.com/llvm/llvm-project/blob/7f93ae808634e33e4dc9bce753c909aa5f9a6eb4/libc/src/__support/UInt.h#L25) Probably you should remove or adjust this?


================
Comment at: libc/src/__support/FPUtil/big_float.h:55
+  template <size_t M_LENGTH, typename = typename cpp::enable_if_t<
+                                 (M_LENGTH > MANTISSA_LENGTH), void>>
+  explicit operator BigFloat<M_LENGTH>() const {
----------------
Will it be better to put `M_LENGTH >= MANTISSA_LENGTH`? For "highly templated" cases it can be easy to generalize such conversion.


================
Comment at: libc/src/__support/FPUtil/big_float.h:75
+  // to be normals.
+  double to_double() const {
+    if (is_zero())
----------------
michaelrj wrote:
> same as above, I think you can make this either an operator or a templated `to_float<T>`
General idea. Probably it is good to have conversion to double double? It can be precise for 64 bits mantissa?


================
Comment at: libc/src/__support/FPUtil/big_float.h:84
+    // Move leading 1 (if non-zero) to the most significant bit of mantissa.
+    if (shift) {
+      e -= shift;
----------------
The if is not needed. The operations in the if statement probably can be even faster than check and conditional jump? 


================
Comment at: libc/src/__support/FPUtil/big_float.h:90
+
+    mantissa_type m_hi(m >> (MANTISSA_LENGTH - 53));
+    auto d_hi = FPBits<double>::create_value(
----------------
Nit: Probably it is good to have 53 54 and 55 like some constexpr?


================
Comment at: libc/src/__support/FPUtil/big_float.h:120
+template <size_t LENGTH>
+constexpr inline pair<BigFloat<LENGTH / 2>> split(const BigFloat<LENGTH> &a) {
+  constexpr size_t SHIFT_LENGTH = LENGTH / 2;
----------------
I'm not an expert in C++ standard, but pair with one template argument looks suspicious for me. Does C++ standard saying how it should be expanded? 


================
Comment at: libc/src/__support/FPUtil/big_float.h:123
+  using mtype = typename BigFloat<SHIFT_LENGTH>::mantissa_type;
+  return {{a.sign, a.exponent, static_cast<mtype>(a.mantissa)},
+          {a.sign, a.exponent + static_cast<int>(SHIFT_LENGTH),
----------------
Is this static cast by standard drop higher part of the variable?


================
Comment at: libc/src/__support/FPUtil/big_float.h:129
+template <size_t LENGTH>
+constexpr BigFloat<LENGTH> quick_add(BigFloat<LENGTH> a, BigFloat<LENGTH> b) {
+  if (unlikely(a.is_zero()))
----------------
Am I understand right, that rounding and sign of zero in this function is not important?


================
Comment at: libc/src/__support/FPUtil/big_float.h:136
+  // Move the leading 1's to the most significant bits.
+  int shift_a = static_cast<int>(a.mantissa.clz());
+  if (shift_a)
----------------
Probably to put this normalization to dedicated function?
1) It is quite general.
2) Remove the code duplication.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136799/new/

https://reviews.llvm.org/D136799



More information about the libc-commits mailing list