新闻中心

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

2025-11-16
浏览次数:
返回列表
定点数通过整数模拟小数运算,适用于无浮点硬件的场景。文章提出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) {} };

关键细节与优化

实现时需注意以下几点:

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

使用示例

下面是一个简单测试:

Zyro AI Background Remover Zyro AI Background Remover

Zyro推出的AI图片背景移除工具

Zyro AI Background Remover 145 查看详情 Zyro AI Background Remover
#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++数值计算与定点数实现的详细内容,更多请关注其它相关文章!


# 是一种  # 南安推广网站怎么选  # 辽阳网站优化套餐有哪些  # 江西抖音网站推广电话  # 聊城网站建设案例展示  # 深泽品牌网站建设报价  # 高校备课资源网站建设  # 乐安网站建设推广费用  # 罗田媒体推广网站有哪些  # 哪家网站推广营销好点啊  # 江宁网站建设  # 都在  # 浮点数  # ai  # 边缘  # 是一个  # 尼克  # 嵌入式系统  # 浮点  # 四舍五入  # cos  # 游戏开发  # stream  # ios  # c++ 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: React/Next.js中实现列表项的动态移动与状态管理:兼论唯一键的重要性  如何仅使用CSS更改登录界面背景图像图标的颜色  在J*a中如何开发简易博客标签推荐系统_博客标签推荐项目实战解析  Win11怎么用U盘重装系统 Win11制作启动盘并重装系统完整教程【详解】  Win11如何使用Windows Sandbox Win11沙盒功能开启与使用教程【详解】  sublime怎么格式化代码_sublime代码美化与一键排版插件配置  《主播少女的秘密账号迷宫》首支宣传片  AO3访问入口汇总 AO3网页版同人作品一键直达  QQ邮箱登录首页官网地址2026 QQ邮箱官方网页入口  c++如何使用TBB库进行任务并行_c++ Intel线程构建模块  如何使 Jest 模拟函数默认抛出错误以提高测试效率  CKEditor 5 自定义构建在React应用中渲染失败的调试与解决  4399网页游戏电脑版全新入口 4399电脑端在线玩指南  qq邮箱发邮件给国外发不出去_QQ邮箱国际邮件发送失败原因与解决  韩剧圈正版入口页面_韩剧圈官网登录链接  KFC套餐升级怎么获取优惠代码_KFC套餐升级活动与优惠代码获取方法  Django表单提交验证失败后保持字段值不刷新  抖音网页版怎么|直播|_抖音网页版开播操作指南  Win11怎么设置开机NumLock亮 Win11修改注册表InitialKeyboardIndicators值  MAC如何安全彻底地删除文件_MAC使用终端命令确保文件无法被恢复  邮政编码查询不到怎么办_邮政编码查询不到的常见原因与对策  如何在Promise链中优雅地中断后续then执行  Python多线程中正确使用sigwait处理SIGALRM信号  限制HTML日期输入框的日期选择范围  怎么在html里运行vbs脚本_html中运行vbs脚本方法【教程】  vivo手机互传视频怎么操作_vivo手机互传视频详细传输方法  C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入  在VS Code中配置和运行Dart程序的完整步骤  Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法  荣耀Play7T运行卡顿解决_荣耀Play7T性能优化  12306选座怎么选到临时改签座_12306改签选座策略与步骤  AI抖音网页版免费视频入口 AI抖音网页端最新视频实时观看  文心一言怎样用插件调度API数据_文心一言用插件调度API数据【API调用】  QQ邮箱在线使用入口 QQ邮箱个人账号网页版登录  《刺客信条4:黑旗》重制版新细节曝光:无缝加载 地图更细致!  Win11怎么开启高性能模式_Windows 11电源计划优化设置  印象笔记如何设离线包出差查阅_印象笔记设离线包出差查阅【离线阅读】  优化MinIO list_objects_v2 操作的性能瓶颈与最佳实践  ArrayList与LinkedList核心操作的Big-O复杂度分析  win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法  Excel文件在线转换快速入口 Excel在线格式转换网站  小猿搜题在线学习页面在哪_小猿搜题在线学习中心入口  正确连接J*aScript到HTML实现可点击图片与自定义事件处理  J*aScript中赋值与自增运算符的复杂交互与执行机制  Win10怎么设置静态IP地址 Win10手动配置IP地址步骤【指南】  蛙漫官网漫画入口地址_蛙漫在线畅读无广告弹窗  C++如何打印当前代码行号与文件名_C++预定义宏FILE与LINE的使用  c++如何使用Catch2编写单元测试_c++简洁易用的BDD风格测试框架  怎么在浏览器上运行HTML文件_浏览器运行HTML文件技巧【技巧】  J*aScript实现单选按钮与关联输入框的联动禁用教程 

搜索