From c5aea8daee8cfa775cd3979dca3e7401f517252f Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Fri, 11 Sep 2020 01:18:54 +0100 Subject: unpack: Replace perfectly readable code with macro abomination. --- unpack.c | 61 ++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/unpack.c b/unpack.c index 1bf0ddf..8f6880b 100644 --- a/unpack.c +++ b/unpack.c @@ -20,36 +20,39 @@ enum endian { BIG, LITTLE }; #define BITMASK(n) (UINTMAX_MAX >> (sizeof (uintmax_t) * CHAR_BIT - n)) -static float ieee754tof(uintmax_t b) -{ - bool isneg; - int exp; - float n; - - isneg = (b >> 31) & 0x1; - exp = (b >> 23) & 0xff; - n = b & 0x7fffff; - - if (exp == 0xff) { - if (n) { - return NAN; - } else { - return isneg ? -INFINITY : INFINITY; - } - } else if (exp == 0) { - if (n == 0) - return isneg ? -0.0 : 0.0; - exp = -126; - } else { - n += 0x1p23f; - exp -= 127; - } - - n = ldexpf(n, exp - 23); - - return isneg ? -n : n; +#define GEN_CONV_IEEE754B(type, total, nexp, nfrac) \ +static type convert_ieee754b##total(uintmax_t b) \ +{ \ + bool isneg; \ + int exp; \ + type n; \ +\ + isneg = (b >> (total - 1)) & 0x1; \ + exp = (b >> nfrac) & BITMASK(nexp); \ + n = b & BITMASK(nfrac); \ +\ + if (exp == BITMASK(nexp)) { \ + if (n) { \ + return NAN; \ + } else { \ + return isneg ? -INFINITY : INFINITY; \ + } \ + } else if (exp == 0) { \ + if (n == 0) \ + return isneg ? -0.0 : 0.0; \ + exp = -(int)(BITMASK(nexp) / 2 - 1); \ + } else { \ + n += 0x1p##nfrac##f; \ + exp -= BITMASK(nexp) / 2; \ + } \ +\ + n = ldexpf(n, exp - nfrac); \ +\ + return isneg ? -n : n; \ } +GEN_CONV_IEEE754B(float, 32, 8, 23) + static uintmax_t read_val(unsigned char *buf, size_t size, enum endian e) { uintmax_t val = 0; @@ -138,7 +141,7 @@ enum pack_status unpack(void *buf_, size_t size, const char *fmt, ...) tr_debug("val.u: %" PRIuMAX, val.u); if (fmt[i] == 'f') { - float f = ieee754tof(val.u); + float f = convert_ieee754b32(val.u); val.f = f; tr_debug("val.f: %f", val.f); } else if (sign) { -- cgit v1.2.3-54-g00ecf