§ Coverage
1/*2 * sc_fixed.c -- implementation. Blocks are tagged with the low-level3 * requirement they satisfy; see requirements/sc_fixed.md.4 */5#include "sc_fixed.h"6#include "sc_sat.h"78#define Q16_INT_MAX ((int32_t)32767)9#define Q16_INT_MIN ((int32_t)(-32768))10#define Q16_HALF ((int64_t)0x8000)11#define Q16_SCALE ((int64_t)0x10000)12132481static sc_q16_t clamp_i64(int64_t v)14{15 sc_q16_t result;16172481 if (v > (int64_t)SC_Q16_MAX)condition outcomes covered 2/218 {192 result = SC_Q16_MAX; /* LLR-FX-13 */20 }212479 else if (v < (int64_t)SC_Q16_MIN)condition outcomes covered 2/222 {232 result = SC_Q16_MIN; /* LLR-FX-14 */24 }25 else26 {272477 result = (sc_q16_t)v; /* LLR-FX-15 */28 }29302481 return result;31}32337sc_q16_t sc_q16_from_int(int32_t value)34{35 sc_q16_t result;36377 if (value > Q16_INT_MAX)condition outcomes covered 2/238 {391 result = SC_Q16_MAX; /* LLR-FX-1 */40 }416 else if (value < Q16_INT_MIN)condition outcomes covered 2/242 {431 result = SC_Q16_MIN; /* LLR-FX-2 */44 }45 else46 {475 result = (sc_q16_t)(value * SC_Q16_ONE); /* LLR-FX-3 */48 }49507 return result;51}52534int32_t sc_q16_to_int(sc_q16_t q)54{554 return (int32_t)(q / SC_Q16_ONE); /* LLR-FX-4 */56}57582058sc_q16_t sc_q16_add(sc_q16_t a, sc_q16_t b)59{602058 return sc_sat_add_i32(a, b); /* LLR-FX-5 */61}62632059sc_q16_t sc_q16_sub(sc_q16_t a, sc_q16_t b)64{652059 return sc_sat_sub_i32(a, b); /* LLR-FX-6 */66}67682477sc_q16_t sc_q16_mul(sc_q16_t a, sc_q16_t b)69{702477 int64_t p = (int64_t)a * (int64_t)b;71722477 if (p >= 0)condition outcomes covered 2/273 {741348 p += Q16_HALF; /* LLR-FX-7: round */75 }76 else77 {781129 p -= Q16_HALF; /* LLR-FX-8: round away */79 }80812477 return clamp_i64(p / Q16_SCALE); /* LLR-FX-9 */82}83847sc_q16_t sc_q16_div(sc_q16_t a, sc_q16_t b)85{86 sc_q16_t result;87887 if (b == 0)condition outcomes covered 2/289 {903 result = (a >= 0) ? SC_Q16_MAX : SC_Q16_MIN; /* LLR-FX-10 */condition outcomes covered 2/291 }92 else93 {944 int64_t n = (int64_t)a * Q16_SCALE;954 result = clamp_i64(n / (int64_t)b); /* LLR-FX-11 */96 }97987 return result;99}1001015sc_q16_t sc_q16_abs(sc_q16_t q)102{103 sc_q16_t result;1041055 if (q == SC_Q16_MIN)condition outcomes covered 2/2106 {1071 result = SC_Q16_MAX; /* LLR-FX-16 */108 }1094 else if (q < 0)condition outcomes covered 2/2110 {1112 result = -q; /* LLR-FX-17 */112 }113 else114 {1152 result = q; /* LLR-FX-18 */116 }1171185 return result;119}1201214sc_q16_t sc_q16_clamp(sc_q16_t q, sc_q16_t lo, sc_q16_t hi)122{123 sc_q16_t result;1241254 if (lo > hi)condition outcomes covered 2/2126 {1271 result = lo; /* LLR-FX-12 */128 }1293 else if (q < lo)condition outcomes covered 2/2130 {1311 result = lo; /* LLR-FX-19 */132 }1332 else if (q > hi)condition outcomes covered 2/2134 {1351 result = hi; /* LLR-FX-20 */136 }137 else138 {1391 result = q; /* LLR-FX-21 */140 }1411424 return result;143}