diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2015-06-08 09:51:47 -0400 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2015-06-08 09:51:47 -0400 |
commit | a6568baf060045cadad1f05af5cfe43e31626b31 (patch) | |
tree | 4471355f7fc25c1549a915a03ab8b14fbeb8783d /floatcomp.c | |
parent | c70ee2ae9fc9fa99c0b3b1af20a7dd0203aaa0d1 (diff) | |
parent | 72882c6a1e76730e6e706941a1a3a855ea023b69 (diff) | |
download | egawk-a6568baf060045cadad1f05af5cfe43e31626b31.tar.gz egawk-a6568baf060045cadad1f05af5cfe43e31626b31.tar.bz2 egawk-a6568baf060045cadad1f05af5cfe43e31626b31.zip |
Merge branch 'master' into feature/cmake
Diffstat (limited to 'floatcomp.c')
-rw-r--r-- | floatcomp.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/floatcomp.c b/floatcomp.c index 16a6d88e..d8d35694 100644 --- a/floatcomp.c +++ b/floatcomp.c @@ -71,6 +71,20 @@ Please port the following code to your weird host; #define AWKNUM_FRACTION_BITS (AWKNUM_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4)) #define DBL_FRACTION_BITS (DBL_MANT_DIG * (FLT_RADIX == 2 ? 1 : 4)) +/* Return the number of trailing zeros in N. N must be nonzero. */ +static int +count_trailing_zeros(uintmax_t n) +{ +#if 3 < (__GNUC__ + (4 <= __GNUC_MINOR__)) && UINTMAX_MAX <= ULLONG_MAX + return __builtin_ctzll(n); +#else + int i = 0; + for (; (n & 3) == 0; n >>= 2) + i += 2; + return i + (1 & ~n); +#endif +} + /* adjust_uint --- fiddle with values, ask Paul Eggert to explain */ uintmax_t @@ -84,8 +98,15 @@ adjust_uint(uintmax_t n) * This is more desirable in practice, since it means the user sees * integers that are the same width as the AWKNUM fractions. */ - if (AWKNUM_FRACTION_BITS < CHAR_BIT * sizeof n) - n &= ((uintmax_t) 1 << AWKNUM_FRACTION_BITS) - 1; + int wordbits = CHAR_BIT * sizeof n; + if (AWKNUM_FRACTION_BITS < wordbits) { + uintmax_t one = 1; + uintmax_t sentinel = one << (wordbits - AWKNUM_FRACTION_BITS); + int shift = count_trailing_zeros(n | sentinel); + uintmax_t mask = (one << AWKNUM_FRACTION_BITS) - 1; + + n &= mask << shift; + } return n; } |