首页 > 后端开发 > C++ > 正文

c++怎么实现一个定点数算术库_C++数值计算与定点数实现

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

c++怎么实现一个定点数算术库_c++数值计算与定点数实现

在嵌入式系统、游戏开发或没有浮点硬件支持的平台上,使用浮点数运算可能效率低下甚至不可行。这时,定点数(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++免费学习笔记(深入)”;

腾讯智影-AI数字人
腾讯智影-AI数字人

基于AI数字人能力,实现7*24小时AI数字人直播带货,低成本实现直播业务快速增增,全天智能在线直播

腾讯智影-AI数字人 73
查看详情 腾讯智影-AI数字人
  • 溢出控制:乘法和除法容易溢出,建议使用 int64_t 中间计算。
  • 四舍五入:在右移时加上偏移量(如 ONE >> 1)可实现四舍五入,提升精度。
  • 构造函数重载冲突:直接用 doubleint 构造可能产生歧义,上面通过私有构造函数规避。
  • 常量表达式支持:使用 constexpr 提升编译期计算能力。
  • 精度选择:16位小数位适合大多数场景;若范围更大可用 8.24 或 32位整数扩展为 64位存储。

使用示例

下面是一个简单测试:

#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
b = 2
c = 7
c > a

基本上就这些。这个定点数类足够轻量,可在无 FPU 的设备上高效运行,同时保持接口简洁。根据具体需求,还可加入 sin/cos 等数学函数查表实现。

以上就是c++++怎么实现一个定点数算术库_C++数值计算与定点数实现的详细内容,更多请关注php中文网其它相关文章!

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号