定点数通过整数模拟小数运算,适用于无浮点硬件的场景。文章提出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,支持不同精度配置:
template<int FractionBits = 16>
class FixedPoint {
private:
int32_t value; // 存储定点数的原始整数值
static constexpr int32_t FRACTION_SHIFT = FractionBits;
static constexpr int32_t ONE = 1 << FractionBits;
<p>public:
// 构造函数
constexpr FixedPoint() : value(0) {}
constexpr FixedPoint(int32_t v) : value(v << FractionBits) {}
constexpr FixedPoint(double v) : value(static_cast<int32_t>(v * ONE)) {}</p><pre class='brush:php;toolbar:false;'>// 转换回浮点数
double toDouble() const { return static_cast<double>(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<int64_t>(value) * rhs.value;
return FixedPoint{ 0, static_cast<int32_t>((temp + (ONE >> 1)) >> FractionBits) }; // 四舍五入
}
FixedPoint operator/(const FixedPoint& rhs) const {
int64_t temp = (static_cast<int64_t>(value) << FractionBits);
return FixedPoint{ 0, static_cast<int32_t>((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 < rhs.value; }
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 >= rhs.value; }
// 支持从原始整数构造(避免歧义)private: struct RawTag {}; public: constexpr FixedPoint(RawTag, int32_t raw) : value(raw) {} };
实现时需注意以下几点:
立即学习“C++免费学习笔记(深入)”;
int64_t 中间计算。ONE >> 1)可实现四舍五入,提升精度。double 和 int 构造可能产生歧义,上面通过私有构造函数规避。constexpr 提升编译期计算能力。下面是一个简单测试:
#include <iostream>
<p>int main() {
FixedPoint<16> a(3.5); // 3.5
FixedPoint<16> b(2.0); // 2.0
FixedPoint<16> c = a * b; // 应得 7.0</p><pre class='brush:php;toolbar:false;'>std::cout << "a = " << a.toDouble() << "\n";
std::cout << "b = " << b.toDouble() << "\n";
std::cout << "c = " << c.toDouble() << "\n";
if (c > a) {
std::cout << "c > a\n";
}
return 0;}
输出:
a = 3.5基本上就这些。这个定点数类足够轻量,可在无 FPU 的设备上高效运行,同时保持接口简洁。根据具体需求,还可加入 sin/cos 等数学函数查表实现。
以上就是c++++怎么实现一个定点数算术库_C++数值计算与定点数实现的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号