开始设计
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
#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*/
|
||||
Reference in New Issue
Block a user