LCOV - code coverage report
Current view: top level - AP_Common - float16.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 29 29 100.0 %
Date: 2026-09-09 11:02:08 Functions: 2 2 100.0 %

          Line data    Source code
       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          58 : float Float16_t::get(void) const
      13             : {
      14             :     union FP32 {
      15             :         uint32_t u;
      16             :         float f;
      17             :     };
      18          58 :     const union FP32 magic = { (254UL - 15UL) << 23U };
      19          58 :     const union FP32 was_inf_nan = { (127UL + 16UL) << 23U };
      20             :     union FP32 out;
      21             : 
      22          58 :     out.u = (v16 & 0x7FFFU) << 13U;
      23          58 :     out.f *= magic.f;
      24          58 :     if (out.f >= was_inf_nan.f) {
      25          12 :         out.u |= 255UL << 23U;
      26             :     }
      27          58 :     out.u |= (v16 & 0x8000UL) << 16U;
      28             : 
      29          58 :     return out.f;
      30             : }
      31             : 
      32          54 : void Float16_t::set(float value)
      33             : {
      34             :     union FP32
      35             :     {
      36             :         uint32_t u;
      37             :         float f;
      38             :     };
      39             : 
      40          54 :     const union FP32 f32inf = { 255UL << 23U };
      41          54 :     const union FP32 f16inf = { 31UL << 23U };
      42          54 :     const union FP32 magic = { 15UL << 23U };
      43          54 :     const uint32_t sign_mask = 0x80000000UL;
      44          54 :     const uint32_t round_mask = 0xFFFFF000UL;
      45             : 
      46             :     union FP32 in;
      47          54 :     in.f = value;
      48          54 :     uint32_t sign = in.u & sign_mask;
      49          54 :     in.u ^= sign;
      50             : 
      51          54 :     v16 = 0;
      52             : 
      53          54 :     if (in.u >= f32inf.u)
      54             :     {
      55           6 :         v16 = (in.u > f32inf.u) ? (uint16_t)0x7FFFU : (uint16_t)0x7C00U;
      56             :     }
      57             :     else
      58             :     {
      59          48 :         in.u &= round_mask;
      60          48 :         in.f *= magic.f;
      61          48 :         in.u -= round_mask;
      62          48 :         if (in.u > f16inf.u)
      63             :         {
      64           2 :             in.u = f16inf.u;
      65             :         }
      66          48 :         v16 = (uint16_t)(in.u >> 13U);
      67             :     }
      68             : 
      69          54 :     v16 |= (uint16_t)(sign >> 16U);
      70          54 : }

Generated by: LCOV version 1.14