/** * @file utils.h */ #ifndef CX9261ADRIVER_UTILS_H #define CX9261ADRIVER_UTILS_H #include #include #include #include namespace CX9261A { #if __cplusplus >= 201703L template constexpr const T& clamp(const T& v, const T& lo, const T& hi) { return std::clamp(v, lo, hi); } #else template constexpr const T& clamp(const T& v, const T& lo, const T& hi) { return std::max(std::min(hi, v), lo); } #endif template int round(Float f) { return static_cast(std::round(f)); } template long long round64(Float f) { return static_cast(std::round(f)); } template int floor(Float f) { return static_cast(std::floor(f)); } template long long floor64(Float f) { return static_cast(std::floor(f)); } template int ceil(Float f) { return static_cast(std::ceil(f)); } template long long ceil64(Float f) { return static_cast(std::ceil(f)); } /** * @brief Register类,提供方便的位操作函数 */ class Register { public: template constexpr Register(const T value = 0) { static_assert(std::is_integral_v, "Register value must be integral!"); m_value = static_cast(value); } /** * 以十进制返回寄存器值 */ unsigned char value() const { return static_cast(m_value.to_ulong()); } /** * 对寄存器值进行部分值的替换操作 * 例:replace(7, 4, 0b1111); 使寄存器的高四位为1 * @param start 起始位 * @param end 中止位 * @param after 要替换的值 */ void replace(const unsigned int start, const unsigned int end, unsigned char after) { for (auto i = end; i <= start; ++i) { m_value[i] = (after >> (i - end)) & 0b1; } } auto operator[](const size_t position) { return m_value[position]; } template operator Type() const { static_assert(std::is_integral_v, "Type must be an integral"); return static_cast(m_value.to_ulong()); } private: std::bitset<8> m_value{}; }; template std::string frac2bin(const double frac) { const long double num = frac * (pow(2.0, N)); std::string ret = std::bitset(std::floor(num)).to_string(); return ret; } } // namespace CX9261A #endif // CX9261ADRIVER_UTILS_H