硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1503|回复: 8
收起左侧

[信号与系统] 实际计算的时候你们会使用浮点数吗?

[复制链接]

97

主题

537

回帖

843

积分

金牌会员

积分
843
发表于 2024-11-19 16:41:34 | 显示全部楼层 |阅读模式
本帖最后由 会飞的猪_2020 于 2024-11-19 16:43 编辑

精度问题产生的错误如何处理,是否还是不如定点数?

前几个月,我把一份在M0芯片上的电机驱动代码,抄到了H7上。

原先是定点数,我想着反正H7有浮点计算的单元,就干脆不用Q格式,直接浮点数做就好。
结果出错了。




伪代码如下:
[C] 纯文本查看 复制代码
 if (SWITCH_TS - Ta - Tb > 0) {
}else{
Ta = (Ta * SWITCH_TS) / (Ta + Tb);
Tb = (Tb * SWITCH_TS) / (Ta + Tb);
}

这个代码的逻辑如下:
这里的Ts就是开关周期,Ta是a相的打开的时间,Tb是b相打开的时间。
物理上限制了Ta+Tb必须小于等于Ts。如果下发的指令让Ta+Tb超过了Ts就要做一个过调制的操作。
上面的代码就是一个简单的过调制的逻辑。这里判断,如果Ta+Tb的时间超过了Ts,如果Ta+Tb大于Ts,就让Ta和Tb按各自的比例分配Ts。

用浮点数做出来会导致后面计算另外一个值T1的时候出现负值,T1的计算方法如下:
[C] 纯文本查看 复制代码
T1 = (SWITCH_TS - Ta -Tb)/4;


理论上如果过调制之后,T1肯定为0,但是浮点数计算出来是负值,导致后面的换算PWM的CRR值的时候出现了很大的值,而不是零。



这个令我很困惑,不知道浮点数的意义在哪里了。哪怕我的芯片有浮点数计算单元,我也要使用定点数吗?




共产主义一定胜利!
回复

使用道具 举报

97

主题

537

回帖

843

积分

金牌会员

积分
843
 楼主| 发表于 2024-11-19 16:49:28 | 显示全部楼层
这种精度丢失无法忍受。
目前由于我个人见识的问题,我觉得最好的解决办法就是使用定点数。

来发帖子就是想请教一下,是否有可以不使用定点数,也能解决这种精度丢失的办法?
共产主义一定胜利!
回复

使用道具 举报

0

主题

37

回帖

37

积分

新手上路

积分
37
发表于 2024-11-19 19:23:18 | 显示全部楼层
我在实际项目中还未遇到过精度损失造成明显影响的,所以在浮点数精度这一块见识也有限。

我个人的看法是:

1. 浮点数的意义是在一定精度下大大扩展了数据表示范围;
2. 浮点数运算精度损失无法避免,但通过调整计算方式可以减少精度损失;
3. 对你的情况,或许将条件改为if (SWITCH_TS - Ta - Tb > 1.0e-6f)会有帮助(我没有测试)?
回复

使用道具 举报

0

主题

37

回帖

37

积分

新手上路

积分
37
发表于 2024-11-19 19:40:39 | 显示全部楼层
不好意思,刚才第三条词不达意,我想表达的是:浮点数和0做对比时,最好使用一个很小的浮点数作为0的替代。
回复

使用道具 举报

0

主题

37

回帖

37

积分

新手上路

积分
37
发表于 2024-11-20 08:58:36 | 显示全部楼层
我昨晚睡前突然想到,你的代码这样写应该就没有问题了:

Ta = (Ta * SWITCH_TS) / (Ta + Tb);
Tb = SWITCH_TS - Ta;

原则就是尽量减少浮点数乘除法运算数量。
回复

使用道具 举报

85

主题

784

回帖

1039

积分

至尊会员

积分
1039
发表于 2024-11-20 09:19:11 | 显示全部楼层
不要直接和0进行比较
回复

使用道具 举报

97

主题

537

回帖

843

积分

金牌会员

积分
843
 楼主| 发表于 2024-11-20 10:55:03 | 显示全部楼层
ME_Engineer 发表于 2024-11-20 08:58
我昨晚睡前突然想到,你的代码这样写应该就没有问题了:

Ta = (Ta * SWITCH_TS) / (Ta + Tb);

是的,这种方法写可以避免。
共产主义一定胜利!
回复

使用道具 举报

2

主题

69

回帖

75

积分

初级会员

积分
75
发表于 2024-11-20 11:07:25 | 显示全部楼层
庄永 发表于 2024-11-20 09:19
不要直接和0进行比较

不能和0比较是绝对了,单纯的浮点数比较是没有问题的,只是浮点数不应该使用==比较是否相等
回复

使用道具 举报

97

主题

537

回帖

843

积分

金牌会员

积分
843
 楼主| 发表于 2024-11-21 13:44:15 | 显示全部楼层
不能和0比较我是知道的。这个问题出现的原因,不能用把代码改成"(SWITCH_TS - Ta - Tb > 1.0e-6f)"来避免。
它核心问题还是
Ta = (Ta * SWITCH_TS) / (Ta + Tb);
Tb = (Tb * SWITCH_TS) / (Ta + Tb);
这样操作之后
Ta+Tb
不等于
SWITCH_TS
共产主义一定胜利!
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-6-9 19:52 , Processed in 0.271190 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表