定点数通过整数模拟小数运算,适用于无浮点硬件的场景。文章提出C++模板类FixedPoint,采用16.16格式(32位整数,16位小数),支持构造、转换、四则运算与比较操作,关键优化包括使用int64_t防止溢出、右移时加偏移实现四舍五入、constexpr提升性能,并通过私有构造避免重载歧义,示例验证了3.5×2.0=7.0的正确性,具备高效、简洁、可移植特点。

在嵌入式系统、游戏开发或没有浮点硬件支持的平台上,使用浮点数运算可能效率低下甚至不可行。这时,定点数(Fixed-Point Arithmetic)是一种高效替代方案。C++ 中可以通过封装类来实现一个灵活、易用的定点数算术库。
什么是定点数?
定点数是用整数来模拟小数的一种方式。它通过固定小数点的位置来表示数值。例如,使用 16.16 格式(32位整数,高16位整数部分,低16位小数部分),数值 3.5 可以表示为:
3.5 × 65536 = 229376。
所有运算都在整数层面进行,最后再按比例转换回真实值。
设计一个定点数类
我们可以定义一个模板类 FixedPoint,支持不同精度配置:
templateclass FixedPoint {private: int32_t value; // 存储定点数的原始整数值 static constexpr int32_t FRACTION_SHIFT = FractionBits; static constexpr int32_t ONE = 1 << FractionBits;public:// 构造函数constexpr FixedPoint() : value(0) {}constexpr FixedPoint(int32_t v) : value(v << FractionBits) {}constexpr FixedPoint(double v) : value(static_cast(v * ONE)) {}
// 转换回浮点数double toDouble() const { return static_cast(value) / ONE; }// 基本运算符重载FixedPoint operator+(const FixedPoint& rhs) const { return FixedPoint{ 0, value + rhs.value }; // 使用私有构造}FixedPoint operator-(const FixedPoint& rhs) const { return FixedPoint{ 0, value - rhs.value };}FixedPoint operator*(const FixedPoint& rhs) const { int64_t temp = static_cast(value) * rhs.value; return FixedPoint{ 0, static_cast((temp + (ONE >> 1)) >> FractionBits) }; // 四舍五入}FixedPoint operator/(const FixedPoint& rhs) const { int64_t temp = (static_cast(value) << FractionBits); return FixedPoint{ 0, static_cast((temp + rhs.value/2) / rhs.value) };}FixedPoint& operator+=(const FixedPoint& rhs) { value += rhs.value; return *this; }FixedPoint& operator-=(const FixedPoint& rhs) { value -= rhs.value; return *this; }FixedPoint& operator*=(const FixedPoint& rhs) { *this = *this * rhs; return *this; }FixedPoint& operator/=(const FixedPoint& rhs) { *this = *this / rhs; return *this; }// 比较操作符bool operator==(const FixedPoint& rhs) const { return value == rhs.value; }bool operator!=(const FixedPoint& rhs) const { return value != rhs.value; }bool operator<(const FixedPoint& rhs) const { return value (const FixedPoint& rhs) const { return value > rhs.value; }bool operator<=(const FixedPoint& rhs) const { return value =(const FixedPoint& rhs) const { return value >= rhs.value; }// 支持从原始整数构造(避免歧义)
private:struct RawTag {};public:constexpr FixedPoint(RawTag, int32_t raw) : value(raw) {}};
关键细节与优化
实现时需注意以下几点:
立即学习“C++免费学习笔记(深入)”;
溢出控制:乘法和除法容易溢出,建议使用 int64_t 中间计算。四舍五入:在右移时加上偏移量(如 ONE >> 1)可实现四舍五入,提升精度。构造函数重载冲突:直接用 double 和 int 构造可能产生歧义,上面通过私有构造函数规避。常量表达式支持:使用 constexpr 提升编译期计算能力。精度选择:16位小数位适合大多数场景;若范围更大可用 8.24 或 32位整数扩展为 64位存储。
使用示例
下面是一个简单测试:
#includeint main() {FixedPoint a(3.5); // 3.5FixedPoint b(2.0); // 2.0FixedPoint c = a * b; // 应得 7.0
std::cout << "a = " << a.toDouble() << "n";std::cout << "b = " << b.toDouble() << "n";std::cout << "c = " << c.toDouble() < a) { std::cout < an";}return 0;
}
输出:
a = 3.5
b = 2
c = 7
c > a
基本上就这些。这个定点数类足够轻量,可在无 FPU 的设备上高效运行,同时保持接口简洁。根据具体需求,还可加入 sin/cos 等数学函数查表实现。
以上就是c++++怎么实现一个定点数算术库_C++数值计算与定点数实现的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1484286.html
微信扫一扫
支付宝扫一扫