[libc-commits] [PATCH] D157156: [libc] Add get_explicit_exponent to fpbits

Michael Jones via Phabricator via libc-commits libc-commits at lists.llvm.org
Fri Aug 4 16:16:09 PDT 2023


michaelrj created this revision.
michaelrj added reviewers: lntue, sivachandra.
Herald added projects: libc-project, All.
Herald added a subscriber: libc-commits.
michaelrj requested review of this revision.

In the same way that get_explicit_mantissa is used to get the mantissa
with all the implicit bits spelled out, get_explicit_exponent gives you
the exponent with the special cases handled. Mainly it handles the cases
where the exponent is zero, which causes the exponent to either be 1
higher than expected, or just 0.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157156

Files:
  libc/src/__support/FPUtil/FPBits.h
  libc/src/__support/FPUtil/x86_64/LongDoubleBits.h


Index: libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
===================================================================
--- libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
+++ libc/src/__support/FPUtil/x86_64/LongDoubleBits.h
@@ -135,11 +135,26 @@
   }
 
   LIBC_INLINE int get_exponent() const {
-    if (get_unbiased_exponent() == 0)
-      return int(1) - EXPONENT_BIAS;
     return int(get_unbiased_exponent()) - EXPONENT_BIAS;
   }
 
+  // If the number is subnormal, the exponent is treated as if it were the
+  // minimum exponent for a normal number. This is to keep continuity between
+  // the normal and subnormal ranges, but it causes problems for functions where
+  // values are calculated from the exponent, since just subtracting the bias
+  // will give a slightly incorrect result. Additionally, zero has an exponent
+  // of zero, and that should actually be treated as zero.
+  LIBC_INLINE int get_explicit_exponent() const {
+    const int unbiased_exp = int(get_unbiased_exponent());
+    if (is_zero()) {
+      return 0;
+    } else if (unbiased_exp == 0) {
+      return 1 - EXPONENT_BIAS;
+    } else {
+      return unbiased_exp - EXPONENT_BIAS;
+    }
+  }
+
   LIBC_INLINE bool is_zero() const {
     return get_unbiased_exponent() == 0 && get_mantissa() == 0 &&
            get_implicit_bit() == 0;
Index: libc/src/__support/FPUtil/FPBits.h
===================================================================
--- libc/src/__support/FPUtil/FPBits.h
+++ libc/src/__support/FPUtil/FPBits.h
@@ -128,6 +128,23 @@
     return int(get_unbiased_exponent()) - EXPONENT_BIAS;
   }
 
+  // If the number is subnormal, the exponent is treated as if it were the
+  // minimum exponent for a normal number. This is to keep continuity between
+  // the normal and subnormal ranges, but it causes problems for functions where
+  // values are calculated from the exponent, since just subtracting the bias
+  // will give a slightly incorrect result. Additionally, zero has an exponent
+  // of zero, and that should actually be treated as zero.
+  LIBC_INLINE int get_explicit_exponent() const {
+    const int unbiased_exp = int(get_unbiased_exponent());
+    if (is_zero()) {
+      return 0;
+    } else if (unbiased_exp == 0) {
+      return 1 - EXPONENT_BIAS;
+    } else {
+      return unbiased_exp - EXPONENT_BIAS;
+    }
+  }
+
   LIBC_INLINE bool is_zero() const {
     // Remove sign bit by shift
     return (bits << 1) == 0;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157156.547392.patch
Type: text/x-patch
Size: 2459 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libc-commits/attachments/20230804/31fbca87/attachment-0001.bin>


More information about the libc-commits mailing list