[技术讨论] KEIL C51 pow()函数误差

[复制链接]
 楼主| baiyunfei.k.f 发表于 2025-7-21 17:38 | 显示全部楼层 |阅读模式
我使用KEIL C51 9.6编译器,单片机STC12F2K60S2。软件中用到extern float pow   (float x, float y);指数函数。仿真发现运行pow(2.0f,26.0f),结果为67108952,但正确的结果应为67,108,864。运行pow(2.0f,27.0f),结果为134217552,但正确的结果应为134,217,728。但是运行pow(2.0f,28.0f)结果为268,435,456,结果正确。这是为什么呢?是float精度不够吗?

评论

[url=home.php?mod=space&uid=1167]@xch[/url] :没有用到中断  发表于 2025-7-24 10:45
xch
测试运算函数前先禁了全局中断,然后看看运算结果  发表于 2025-7-22 14:32
飞思啦 发表于 2025-7-22 09:38 | 显示全部楼层
是否是库有问题,C库
 楼主| baiyunfei.k.f 发表于 2025-7-22 09:45 | 显示全部楼层
飞思啦 发表于 2025-7-22 09:38
是否是库有问题,C库

pow();幂函数是math.h里面的
dffzh 发表于 2025-7-22 10:27 | 显示全部楼层
本帖最后由 dffzh 于 2025-7-22 10:34 编辑

你用的是8位单片机吧,程序中为什么要用浮点数作为pow的入参呢,你直接用pow(整型数据,整型数据)试试;
对于更大的指数(如28),虽然数值更大,但可能恰好落在能精确表示的区间。
另外,你可以用移位操作来代替pow函数实现你需要的功能,可以试一下效果。
xch 发表于 2025-7-22 14:25 | 显示全部楼层
我在IAR 中测试了 pow 函数,结果都是正确的。
xch 发表于 2025-7-22 14:30 | 显示全部楼层
设三个断点观察SpiTxCnt, 运算结果都与楼主说的“正确”结果相同。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
R2D2 发表于 2025-7-22 15:02 | 显示全部楼层
再正常不过了,IEEE754单精度就是这个水平。
gaoyang9992006 发表于 2025-7-22 16:56 | 显示全部楼层
pow(2.0f, 26.0f) 的数学结果是 67,108,864(0x4000000),但 float 可能将其存储为近似值 67,108,952(误差+88)。

类似地,pow(2.0f, 27.0f) 的误差被放大到 +176。

而 pow(2.0f, 28.0f) 恰好能被 float 精确表示,因此结果正确。

评论

给技术高点赞  发表于 2025-7-24 09:53
567 发表于 2025-7-23 23:00 | 显示全部楼层
本帖最后由 567 于 2025-7-23 23:02 编辑

不要说函数误差了。
你直接给一个浮点数赋值134217728,然后读出来看看是多少?
float的精度有限。
地瓜patch 发表于 2025-7-24 09:54 | 显示全部楼层
567 发表于 2025-7-23 23:00
不要说函数误差了。
你直接给一个浮点数赋值134217728,然后读出来看看是多少?
float的精度有限。 ...

这个思路好,写进去再读出来,就产生误差了
 楼主| baiyunfei.k.f 发表于 2025-7-24 10:53 | 显示全部楼层
dffzh 发表于 2025-7-22 10:27
你用的是8位单片机吧,程序中为什么要用浮点数作为pow的入参呢,你直接用pow(整型数据,整型数据)试试;
对 ...

是宏晶的51单片机。有个浮点数的运算要求。float pow   (float x, float y),形参是float类型
 楼主| baiyunfei.k.f 发表于 2025-7-24 10:55 | 显示全部楼层
xch 发表于 2025-7-22 14:25
我在IAR 中测试了 pow 函数,结果都是正确的。

用KEIL的arm编译器,在stm32上运行,结果也是正确的。用C51编译器,在51单片机上运行结果不对。
 楼主| baiyunfei.k.f 发表于 2025-7-24 10:56 | 显示全部楼层
xch 发表于 2025-7-22 14:30
设三个断点观察SpiTxCnt, 运算结果都与楼主说的“正确”结果相同。

STM32芯片运行结果是正确的
 楼主| baiyunfei.k.f 发表于 2025-7-24 13:39 | 显示全部楼层
567 发表于 2025-7-23 23:00
不要说函数误差了。
你直接给一个浮点数赋值134217728,然后读出来看看是多少?
float的精度有限。 ...

试了一下,读出来和赋值一样

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

117

主题

574

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部