pursuing 发表于 2024-2-22 12:25:24

宏定义中加2是为了自动实现四舍五入?

本帖最后由 pursuing 于 2024-2-22 12:29 编辑

我在学习《STC8H》pdf手册,其中 17.10.4 串口 2 使用定时器 2 做波特率发生器 章节中,有下面的宏定义:

#define FOSC 11059200UL
#define BRT (65536 - (FOSC / 115200+2) / 4)//加 2 操作是为了让 Keil 编译器自动实现四舍五入运算

我认为这个注释是不是有问题?因为C语言的除法是小数直接丢弃,不存在四舍五入吧。应该是99/4=24和(99+2)/4=25这种区别。
而就这里频率设11059200而言,除以115200,正好等于96,加不加2 除以4,结果也都是24,仿真也验证了。应该是其他频率时产生99/4和101/4这种区别。
如我说的不对,请大家帮忙指正,谢谢!另外,如能更进一步解释一下这是怎么来的,就更感谢了!


tzz1983 发表于 2024-2-22 13:03:37

本帖最后由 tzz1983 于 2024-2-22 14:01 编辑

(65536 - (FOSC / 115200+2) / 4)    // 加2后跟除4, 实际上就是+0.5 => (65536 -( (FOSC / 115200) / 4+0.5 ))提前加2是为了计算顺序时不被提前舍去

// 如果((FOSC / 115200) / 4)结果的余数大于0.5, 则加0.5后取整时自动进1, 否则加了0.5也凑不齐1,取整时自动舍去了,

所以这就是4舍5入

以你的例举的数据来说, 99除4= 24.75取25比取24合理   实际上(99+2)/4=25余0.25舍去, 验证结果正确






神农鼎 发表于 2024-2-22 14:47:19

神来之笔,醉了,爱了

21cnsound 发表于 2024-2-22 14:48:41

以前写汇编时用过,加上除数的一半再除即可实现四舍五入的效果,具体原理可以参考楼上所说,稍微琢磨一下就明白了。或者你用加5后除以10来算更容易理解:
(0+5)//10=0
(1+5)//10=0
(2+5)//10=0
(3+5)//10=0
(4+5)//10=0
(5+5)//10=1
(6+5)//10=1
(7+5)//10=1
(8+5)//10=1
(9+5)//10=1
(10+5)//10=1
(11+5)//10=1
(12+5)//10=1
(13+5)//10=1
(14+5)//10=1
(15+5)//10=2

pursuing 发表于 2024-2-22 16:13:44

谢谢楼上几位朋友的讲解,说加0.5我就明白了。{:4_197:}{:4_197:}

wangxiangtan 发表于 2024-2-22 16:37:42

还能这样搞,学习了学习了
页: [1]
查看完整版本: 宏定义中加2是为了自动实现四舍五入?