新闻中心
c++怎么实现一个定点数算术库_C++数值计算与定点数实现
定点数通过整数模拟小数运算,适用于无浮点硬件的场景。文章提出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) {} };
关键细节与优化
实现时需注意以下几点:
-
溢出控制:乘法和除法容易溢出,建议使用
int64_t中间计算。 -
四舍五入:在右移时加上偏移量(如
ONE >> 1)可实现四舍五入,提升精度。 -
构造函数重载冲突:直接用
double和int构造可能产生歧义,上面通过私有构造函数规避。 -
常量表达式支持:使用
constexpr提升编译期计算能力。 - 精度选择:16位小数位适合大多数场景;若范围更大可用 8.24 或 32位整数扩展为 64位存储。
使用示例
下面是一个简单测试:
Zyro AI Background Remover
Zyro推出的AI图片背景移除工具
145
查看详情
#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.5b = 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实现单选按钮与关联输入框的联动禁用教程


2025-11-16
浏览次数:次
返回列表
// 构造函数
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; }
// 支持从原始整数构造(避免歧义)