aboutsummaryrefslogtreecommitdiffstats
path: root/ieee754b.c
diff options
context:
space:
mode:
Diffstat (limited to 'ieee754b.c')
-rw-r--r--ieee754b.c43
1 files changed, 43 insertions, 0 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)