Files
cAI/cKit/Foundation/c_Float.h
T
2026-08-10 01:21:15 +08:00

204 lines
5.7 KiB
C

#ifndef INCLUDED_C_FLOAT_H
#define INCLUDED_C_FLOAT_H
#ifndef INCLUDED_C_BASE_H
#include <c_Base.h>
#endif /*INCLUDED_C_BASE_H*/
#ifndef INCLUDED_MATH_H
#define INCLUDED_MATH_H
#include <math.h>
#endif /*INCLUDED_MATH_H*/
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
typedef union {
float f;
struct {
uint32_t fraction : 23; // 尾数 (M)
uint32_t exponent : 8; // 指数 (E)
uint32_t sign : 1; // 符号位 (S)
} parts;
uint32_t raw;
} c_Float_t;
typedef union {
double d;
struct {
uint64_t fraction : 52; // 尾数
uint64_t exponent : 11; // 指数
uint64_t sign : 1; // 符号
} parts;
uint64_t raw;
} 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
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
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*/