CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
Ardupilot

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: Ardupilot/ardupilot
Path: blob/master/libraries/AP_Common/float16.cpp
Views: 1798
1
#include "float16.h"
2
/*
3
float16 implementation
4
5
Note that this is IEEE half-precision 16-bit float, *not* bfloat16
6
7
algorithm with thanks to libcanard:
8
https://github.com/dronecan/libcanard
9
*/
10
11
12
float Float16_t::get(void) const
13
{
14
union FP32 {
15
uint32_t u;
16
float f;
17
};
18
const union FP32 magic = { (254UL - 15UL) << 23U };
19
const union FP32 was_inf_nan = { (127UL + 16UL) << 23U };
20
union FP32 out;
21
22
out.u = (v16 & 0x7FFFU) << 13U;
23
out.f *= magic.f;
24
if (out.f >= was_inf_nan.f) {
25
out.u |= 255UL << 23U;
26
}
27
out.u |= (v16 & 0x8000UL) << 16U;
28
29
return out.f;
30
}
31
32
void Float16_t::set(float value)
33
{
34
union FP32
35
{
36
uint32_t u;
37
float f;
38
};
39
40
const union FP32 f32inf = { 255UL << 23U };
41
const union FP32 f16inf = { 31UL << 23U };
42
const union FP32 magic = { 15UL << 23U };
43
const uint32_t sign_mask = 0x80000000UL;
44
const uint32_t round_mask = 0xFFFFF000UL;
45
46
union FP32 in;
47
in.f = value;
48
uint32_t sign = in.u & sign_mask;
49
in.u ^= sign;
50
51
v16 = 0;
52
53
if (in.u >= f32inf.u)
54
{
55
v16 = (in.u > f32inf.u) ? (uint16_t)0x7FFFU : (uint16_t)0x7C00U;
56
}
57
else
58
{
59
in.u &= round_mask;
60
in.f *= magic.f;
61
in.u -= round_mask;
62
if (in.u > f16inf.u)
63
{
64
in.u = f16inf.u;
65
}
66
v16 = (uint16_t)(in.u >> 13U);
67
}
68
69
v16 |= (uint16_t)(sign >> 16U);
70
}
71
72