#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*/ #ifndef INCLUDED_FLOAT_H #define INCLUDED_FLOAT_H #include #endif /*INCLUDED_FLOAT_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ typedef union { float f; uint32_t raw; struct { uint32_t fraction : 23; // 尾数 (M) uint32_t exponent : 8; // 指数 (E) uint32_t sign : 1; // 符号位 (S) } parts; } c_Float_t; typedef union { double d; uint64_t raw; struct { uint64_t fraction : 52; // 尾数 uint64_t exponent : 11; // 指数 uint64_t sign : 1; // 符号 } parts; } c_Double_t; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ // 32位单精度常量定义 #define C_FLOAT_SIGN_MASK 0x80000000U #define C_FLOAT_EXP_MASK 0x7F800000U #define C_FLOAT_FRAC_MASK 0x007FFFFFU #define C_FLOAT_HIDDEN_BIT 0x00800000U // 隐藏的最高位1 #define C_FLOAT_EXP_BIAS 127 #define C_FLOAT_NEG_INF 0xFF800000U #define C_FLOAT_POS_INF 0x7F800000U // 快捷提取宏 #define C_FLOAT_GET_SIGN(u) (((u) & C_FLOAT_SIGN_MASK) >> 31) #define C_FLOAT_GET_EXP(u) (((u) & C_FLOAT_EXP_MASK) >> 23) #define C_FLOAT_GET_FRAC(u) ((u) & C_FLOAT_FRAC_MASK) #define C_DOUBLE_SIGN_MASK 0x8000000000000000ULL #define C_DOUBLE_EXP_MASK 0x7FF0000000000000ULL #define C_DOUBLE_FRAC_MASK 0x000FFFFFFFFFFFFFULL #define C_DOUBLE_HIDDEN_BIT 0x0010000000000000ULL // 第52位(从0开始算) #define C_DOUBLE_POS_INF 0x7FF0000000000000ULL #define C_DOUBLE_NEG_INF 0xFFF0000000000000ULL #define C_DOUBLE_GET_SIGN(u) (((u) & C_DOUBLE_SIGN_MASK) >> 63) #define C_DOUBLE_GET_EXP(u) (((u) & C_DOUBLE_EXP_MASK) >> 52) #define C_DOUBLE_GET_FRAC(u) ((u) & C_DOUBLE_FRAC_MASK) /* ------------------------------------------------------------------------------------------------------------------ */ /* */ C_STATIC_FORCE_INLINE uint32_t c_Float_Pack(const uint32_t sign, const uint32_t exp, const uint32_t frac) { return ((sign << 31) & C_FLOAT_SIGN_MASK) | ((exp << 23) & C_FLOAT_EXP_MASK) | (frac & C_FLOAT_FRAC_MASK); } C_STATIC_FORCE_INLINE int c_Float_IsNAN(uint32_t raw) { return ((raw & C_FLOAT_EXP_MASK) == C_FLOAT_EXP_MASK) && ((raw & C_FLOAT_FRAC_MASK) != 0); } C_STATIC_FORCE_INLINE int c_Double_IsNAN(uint64_t raw) { return ((raw & C_DOUBLE_EXP_MASK) == C_DOUBLE_EXP_MASK) && ((raw & C_DOUBLE_FRAC_MASK) != 0); } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ uint32_t c_Float_Add(uint32_t a, uint32_t b); uint32_t c_Float_Mul(uint32_t a, uint32_t b); uint32_t c_Float_Div(uint32_t a, uint32_t b); int c_Float_Cmp(uint32_t a, uint32_t b); C_STATIC_FORCE_INLINE uint32_t c_Float_Sub(uint32_t a, uint32_t b) { // 透過與 0x80000000 進行 XOR,直接將 b 的符號位元取反 (0->1, 1->0) // 隨後將 A - B 轉換為 A + (-B) 傳入加法器 return c_Float_Add(a, b ^ C_FLOAT_SIGN_MASK); } C_STATIC_FORCE_INLINE bool c_Float_IsZero(uint32_t raw) { // Strip away the sign bit; check if the remaining 31 bits are 0 return (raw & ~C_FLOAT_SIGN_MASK) == 0U; } C_STATIC_FORCE_INLINE bool c_Float_IsInf(uint32_t raw) { // Strip the sign bit and check if it exactly matches the exponent mask. // If any fraction bits were set, it would be a NaN instead of Infinity. return (raw & ~0x80000000U) == C_FLOAT_EXP_MASK; } /** * @brief Determines if the float is specifically Negative Infinity (-Inf). */ C_STATIC_FORCE_INLINE bool c_Float_IsNegInf(uint32_t raw) { return raw == C_FLOAT_NEG_INF; } /** * @brief Determines if the float is specifically Positive Infinity (+Inf). */ C_STATIC_FORCE_INLINE bool c_Float_IsPosInf(uint32_t raw) { return raw == C_FLOAT_POS_INF; } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ uint64_t c_Double_Pack(uint32_t sign, int32_t exp, uint64_t frac64); int c_Double_Cmp(uint64_t a, uint64_t b); uint64_t c_Double_Add(uint64_t a, uint64_t b); C_STATIC_FORCE_INLINE uint64_t c_Double_Sub(uint64_t a, uint64_t b) { // A - B == A + (-B) return c_Double_Add(a, b ^ C_DOUBLE_SIGN_MASK); } uint64_t c_Double_Mul(uint64_t a, uint64_t b); uint64_t c_Double_Div(uint64_t a, uint64_t b); C_STATIC_FORCE_INLINE bool c_Double_IsZero(const uint64_t raw) { // Strip away the sign bit; check if the remaining 63 bits are 0 return (raw & ~C_DOUBLE_SIGN_MASK) == 0ULL; } C_STATIC_FORCE_INLINE bool c_Double_IsInf(uint64_t raw) { // Strip the sign bit and check if it exactly matches the exponent mask. // If any fraction bits were set, it would be a NaN instead of Infinity. return (raw & ~C_DOUBLE_SIGN_MASK) == C_DOUBLE_EXP_MASK; } /** * @brief Determines if the double is specifically Negative Infinity (-Inf). */ C_STATIC_FORCE_INLINE bool c_Double_IsNegInf(uint64_t raw) { return raw == C_DOUBLE_NEG_INF; } /** * @brief Determines if the double is specifically Positive Infinity (+Inf). */ C_STATIC_FORCE_INLINE bool c_Double_IsPosInf(uint64_t raw) { return raw == C_DOUBLE_POS_INF; } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ C_STATIC_FORCE_INLINE int c_float_cmp(const float a, const float b) { c_Float_t va; c_Float_t vb; va.f = a; vb.f = b; return c_Float_Cmp(va.raw, vb.raw); } C_STATIC_FORCE_INLINE int c_double_cmp(const double a, const double b) { c_Double_t va; c_Double_t vb; va.d = a; vb.d = b; return c_Double_Cmp(va.raw, vb.raw); } #endif /*INCLUDED_C_FLOAT_H*/