aboutsummaryrefslogtreecommitdiffstats
path: root/ieee754b.c
blob: bf418a8dcf5a9c7dec614c73ea78647b556d3eba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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)