summaryrefslogtreecommitdiff
path: root/src/nbits_ulong.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nbits_ulong.c')
-rw-r--r--src/nbits_ulong.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/nbits_ulong.c b/src/nbits_ulong.c
index 13bf11cd3..4f6d35110 100644
--- a/src/nbits_ulong.c
+++ b/src/nbits_ulong.c
@@ -1,4 +1,5 @@
/* mpfr_nbits_ulong -- number of significant bits in an unsigned long
+ mpfr_nbits_uj -- number of significant bits in an uintmax_t
Copyright 2018-2021 Free Software Foundation, Inc.
Contributed by the AriC and Caramba projects, INRIA.
@@ -21,6 +22,7 @@ https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
#define MPFR_NEED_LONGLONG_H /* for count_leading_zeros */
+#define MPFR_NEED_INTMAX_H
#include "mpfr-impl.h"
/* count the number of significant bits of n, i.e.,
@@ -81,3 +83,55 @@ mpfr_nbits_ulong (unsigned long n)
MPFR_ASSERTD (cnt >= 0);
return cnt;
}
+
+#ifdef _MPFR_H_HAVE_INTMAX_T
+/* count the number of significant bits of n, i.e.,
+ nbits(uintmax_t) - count_leading_zeros (n) */
+int
+mpfr_nbits_uj (uintmax_t n)
+{
+ int cnt;
+
+ MPFR_ASSERTD (n > 0);
+
+ cnt = 0;
+
+ while (n >= 0x10000)
+ {
+ n >>= 16;
+ cnt += 16;
+ }
+
+ MPFR_ASSERTD (n <= 0xffff);
+
+ if (n >= 0x100)
+ {
+ n >>= 8;
+ cnt += 8;
+ }
+
+ MPFR_ASSERTD (n <= 0xff);
+
+ if (n >= 0x10)
+ {
+ n >>= 4;
+ cnt += 4;
+ }
+
+ MPFR_ASSERTD (n <= 0xf);
+
+ if (n >= 4)
+ {
+ n >>= 2;
+ cnt += 2;
+ }
+
+ MPFR_ASSERTD (n <= 3);
+
+ /* now n = 1, 2, or 3 */
+ cnt += 1 + (n >= 2);
+
+ MPFR_ASSERTD (cnt >= 0);
+ return cnt;
+}
+#endif