diff options
-rw-r--r-- | ieee754b.c | 43 | ||||
-rw-r--r-- | ieee754b.h | 15 | ||||
-rwxr-xr-x | libpack.so.do | 2 | ||||
-rwxr-xr-x | test.do | 2 | ||||
-rw-r--r-- | unpack.c | 40 |
5 files changed, 63 insertions, 39 deletions
diff --git a/ieee754b.c b/ieee754b.c new file mode 100644 index 0000000..bf418a8 --- /dev/null +++ b/ieee754b.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2021 Tomasz Kramkowski <tk@the-tk.com> + * SPDX-License-Identifier: MIT + */ +#include <math.h> +#include <stdbool.h> + +#include "common.h" +#include "ieee754b.h" + +#define GEN_IEEE754B_DESER(type, total, nexp, nfrac) \ +type ieee754b##total##_deserialise(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_IEEE754B_DESER(float, 32, 8, 23) +GEN_IEEE754B_DESER(double, 64, 11, 52) diff --git a/ieee754b.h b/ieee754b.h new file mode 100644 index 0000000..bb6266f --- /dev/null +++ b/ieee754b.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2021 Tomasz Kramkowski <tk@the-tk.com> + * SPDX-License-Identifier: MIT + */ +#ifndef PACK_IEEE754B_H +#define PACK_IEEE754B_H + +#include <stdint.h> + +float ieee754b32_deserialise(uintmax_t b32); +double ieee754b64_deserialise(uintmax_t b64); +uintmax_t ieee754b32_serialise(float f); +uintmax_t ieee754b64_serialise(double d); + +#endif // !PACK_IEEE754B_H diff --git a/libpack.so.do b/libpack.so.do index d656dbc..6ab78e5 100755 --- a/libpack.so.do +++ b/libpack.so.do @@ -1,4 +1,4 @@ #!/bin/bash -e -objects=(common.o pack.o trace.o unpack.o) +objects=(common.o pack.o trace.o unpack.o ieee754b.o) redo-ifchange .link-library "${objects[@]}" . ./.link-library @@ -1,4 +1,4 @@ #!/bin/bash -e -objects=(common.o pack.o test.o trace.o unpack.o) +objects=(common.o pack.o test.o trace.o unpack.o ieee754b.o) redo-ifchange .link-executable "${objects[@]}" . ./.link-executable @@ -5,50 +5,16 @@ #include <ctype.h> #include <errno.h> #include <inttypes.h> -#include <math.h> #include <stdarg.h> #include <stdbool.h> #include <stdint.h> #include <stdlib.h> #include "common.h" +#include "ieee754b.h" #include "pack.h" #include "trace.h" -#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) -GEN_CONV_IEEE754B(double, 64, 11, 52) - static uintmax_t read_val(const unsigned char *buf, size_t size, enum endian e) { uintmax_t val = 0; @@ -149,11 +115,11 @@ enum pack_status unpack(const void *buf_, size_t size, const char *fmt, ...) tr_debug("val.u: %" PRIuMAX ", at: %zu", val.u, offset + s * j); if (fmt[i] == 'f') { - float f = convert_ieee754b32(val.u); + float f = ieee754b32_deserialise(val.u); val.f = f; tr_debug("val.f: %f", val.f); } else if (fmt[i] == 'd') { - double d = convert_ieee754b64(val.u); + double d = ieee754b64_deserialise(val.u); val.d = d; tr_debug("val.d: %f", val.d); } else if (sign) { |