Skip to content

Commit 7bd38fd

Browse files
committed
Convert float16 to float 64 to inline function
1 parent b846220 commit 7bd38fd

2 files changed

Lines changed: 40 additions & 42 deletions

File tree

src/float16_conversion.c

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/float16_conversion.h

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,42 @@
11
#include "grumpy.h"
22

3-
double float16_to_float64(uint16_t float16_value);
3+
/* this function is based on the float16->float32 implementation found at
4+
* https://gist.github.com/milhidaka/95863906fe828198f47991c813dbe233
5+
* as well as the process described
6+
* https://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/
7+
*/
8+
static inline double float16_to_float64(uint16_t float16_value) {
9+
// float16=1bit: sign, 5bit: exponent, 10bit: fraction
10+
// float64=1bit: sign, 11bit: exponent, 52bit: fraction
11+
const uint64_t sign = float16_value >> 15;
12+
uint64_t exponent = (float16_value >> 10) & 0x1F;
13+
uint64_t fraction = (float16_value & 0x3FF);
14+
uint64_t float64_value;
15+
double res;
16+
if (exponent == 0) {
17+
if (fraction == 0) {
18+
/* zero */
19+
float64_value = (sign << 63);
20+
} else {
21+
/* denormalised number */
22+
exponent = 1023 - 14;
23+
while ((fraction & (1 << 10)) == 0) {
24+
exponent--;
25+
fraction <<= 1;
26+
}
27+
fraction &= 0x3FF;
28+
float64_value = (sign << 63) | (exponent << 52) | (fraction << 42);
29+
}
30+
} else if (exponent == 0x1F) {
31+
/* Inf or NaN */
32+
float64_value = (sign << 63) | (0x7FFULL << 52) | (fraction << 42);
33+
} else {
34+
/* ordinary number */
35+
float64_value = (sign << 63) | ((exponent + (1023-15)) << 52) | (fraction << 42);
36+
}
37+
38+
// we do this to avoid GCC warnings about casting uint64_t to double
39+
memcpy(&res, &float64_value, sizeof(double));
40+
return res;
41+
}
42+

0 commit comments

Comments
 (0)