#ifndef INCLUDED_C_FLOAT_H #define INCLUDED_C_FLOAT_H #ifndef INCLUDED_C_TYPES_H #include #endif /*INCLUDED_C_TYPES_H*/ #ifndef INCLUDED_MATH_H #define INCLUDED_MATH_H #include #endif /*INCLUDED_MATH_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ /* Complete IEEE 754 Standard Width Type Definition Constraints [1] */ typedef float c_float_t; typedef double c_double_t; /* ================================================================================================================== */ /* 32-bit Single Precision IEEE 754 Bitfields Layout [1] */ typedef struct { uint32_t sign : 1; /* Bit 31: Sign [1] */ uint32_t exponent : 8; /* Bits 30-23: Biased Exponent [1] */ uint32_t mantissa : 23; /* Bits 22-0: Fractional Significand [1] */ } c_IEEE754_Float_Layout_t; typedef union { c_float_t value; uint32_t bits; c_IEEE754_Float_Layout_t layout; } c_Float_Cast_t; /* ================================================================================================================== */ /* 64-bit Double Precision IEEE 754 Bitfields Layout [1] */ typedef struct { #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) uint64_t sign : 1; /* Bit 63 [1] */ uint64_t exponent : 11; /* Bits 62-52 [1] */ uint64_t mantissa : 52; /* Bits 51-0 [1] */ #else /* Little Endian Bitfield Ordering Layout Configuration */ uint64_t mantissa : 52; /* Bits 0-51 [1] */ uint64_t exponent : 11; /* Bits 52-62 [1] */ uint64_t sign : 1; /* Bit 63 [1] */ #endif } c_IEEE754_Double_Layout_t; typedef union { c_double_t value; uint64_t bits; c_IEEE754_Double_Layout_t layout; } c_Double_Cast_t; /* ================================================================================================================== */ /* Core Inline Bit-Level Inspection Queries */ C_STATIC_FORCE_INLINE uint32_t c_Float_ToBits(c_float_t f) { c_Float_Cast_t cast; cast.value = f; return cast.bits; } C_STATIC_FORCE_INLINE c_float_t c_Float_FromBits(uint32_t bits) { c_Float_Cast_t cast; cast.bits = bits; return cast.value; } C_STATIC_FORCE_INLINE uint64_t c_Double_ToBits(c_double_t d) { c_Double_Cast_t cast; cast.value = d; return cast.bits; } C_STATIC_FORCE_INLINE c_double_t c_Double_FromBits(uint64_t bits) { c_Double_Cast_t cast; cast.bits = bits; return cast.value; } C_STATIC_FORCE_INLINE bool c_Float_IsNaN(c_float_t f) { c_Float_Cast_t cast; cast.value = f; /* IEEE 754 rule: Exponent is all 1s, Mantissa is non-zero [1] */ return (cast.layout.exponent == 0xFF) && (cast.layout.mantissa != 0); } C_STATIC_FORCE_INLINE bool c_Double_IsNaN(c_double_t d) { c_Double_Cast_t cast; cast.value = d; /* IEEE 754 rule: Exponent is all 1s (0x7FF), Mantissa is non-zero [1] */ return (cast.layout.exponent == 0x7FF) && (cast.layout.mantissa != 0); } /* ================================================================================================================== */ /* Generic Callback Comparators (Perfect for Heaps & Sort Engines) */ /** * @brief Standard generic min-heap comparator for single-precision c_float_t elements. * @return < 0 if a < b, 0 if a == b, > 0 if a > b */ C_STATIC_FORCE_INLINE int c_Compare_FloatMin(const void* a, const void* b, void* args) { c_float_t val_a = *(const c_float_t*)a; c_float_t val_b = *(const c_float_t*)b; (void)args; return (val_a > val_b) - (val_a < val_b); /* Highly optimized branchless pattern */ } /** * @brief Standard generic min-heap comparator for double-precision c_double_t elements. * @return < 0 if a < b, 0 if a == b, > 0 if a > b */ C_STATIC_FORCE_INLINE int c_Compare_DoubleMin(const void* a, const void* b, void* args) { c_double_t val_a = *(const c_double_t*)a; c_double_t val_b = *(const c_double_t*)b; (void)args; return (val_a > val_b) - (val_a < val_b); } /* ================================================================================================================== */ /* Epsilon Tolerant Mathematical Assertions */ /** * @brief Checks if two single-precision floats are practically equal under an epsilon boundary. */ C_STATIC_FORCE_INLINE bool c_Float_AlmostEquals(c_float_t a, c_float_t b, c_float_t epsilon) { /* If exactly equal (or both are positive/negative infinity), shortcut out */ if (a == b) return true; return fabs(a - b) <= epsilon; } /** * @brief Checks if two double-precision floats are practically equal under an epsilon boundary. */ C_STATIC_FORCE_INLINE bool c_Double_AlmostEquals(c_double_t a, c_double_t b, c_double_t epsilon) { if (a == b) return true; return fabs(a - b) <= epsilon; } #endif /*INCLUDED_C_FLOAT_H*/