打印
[开发工具]

没人用printf打印浮点数嘛?这么大的BUG为啥没人提过?

[复制链接]
1595|18
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
scu319hy|  楼主 | 2024-1-18 16:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
参考了网上各种关于配置printf的资料,在官方发布的arm gcc上就没有能正确打印浮点数的。
翻出若干年前自己写的c库,把printf相关代码移植过来,依旧打印不出来。
但使用segger embeded studio带的gcc版本就可以,无论是它自己带的库还是我的库都正常。用MDK,IAR的编译器也是正常的。

研究了一通,发现原来是arm gcc的变长参数处理逻辑有问题。
内建的va_arg读取8字节的参数没有处理对齐,但编译器生成的调用栈是有"对齐"动作的。
为啥打引号?
因为编译器生成的调用栈并没有真的对齐内存地址,它只是按eabi的传参逻辑进行了“奇/偶”对齐
对于变长参数来说,反正是全入栈,这个奇偶对齐没有什么用处。只会让va_arg的相关逻辑失效。
这个操作还会把原本对齐到内存边界的数据搞成不对齐的。

llvm for embeded arm也有相同的毛病。
最后还是我自己写了个支持参数“对齐”的va_arg才解决问题。

这么明显的问题,在网上没见有人提过。难道是我使用gcc的姿势不对?
arm eabi的spec中也是恰到好处的缺少关于变长参数的相关约定(或者是我眼瞎没看到?)

使用特权

评论回复
沙发
Diyer123| | 2024-1-18 19:52 | 只看该作者
楼主啰啰嗦嗦一大堆……不知编程界有句名言么:
Talk is cheap, Show your code.

使用特权

评论回复
板凳
[鑫森淼焱垚]| | 2024-1-19 10:09 | 只看该作者

对于 GCC 编译器,默认没有启用浮点打印,需要手动开启,即链接器增加 -u _printf_float 选项。

参见帖子:
https://stackoverflow.com/questions/28334435/stm32-printf-float-variable

使用特权

评论回复
地板
Addition| | 2024-1-19 11:26 | 只看该作者
你真NB,scu319hy哥

使用特权

评论回复
评论
scu319hy 2024-1-19 11:51 回复TA
感谢捧场 
5
scu319hy|  楼主 | 2024-1-19 11:49 | 只看该作者
[鑫森淼焱垚] 发表于 2024-1-19 10:09
对于 GCC 编译器,默认没有启用浮点打印,需要手动开启,即链接器增加 -u _printf_float 选项。

参见帖子 ...

你确定连va_arg都不能工作的情况下,加个链接参数就能管用?
要是加个参数调整gcc的参数入栈行为,倒有可能解决这个问题

使用特权

评论回复
6
shenxiaolin| | 2024-1-19 12:57 | 只看该作者
fprintf?

使用特权

评论回复
7
q794625920| | 2024-10-30 15:12 | 只看该作者
[鑫森淼焱垚] 发表于 2024-1-19 10:09
对于 GCC 编译器,默认没有启用浮点打印,需要手动开启,即链接器增加 -u _printf_float 选项。

参见帖子 ...

我加了这个参数确实有用

使用特权

评论回复
8
白马过平川| | 2025-1-24 07:43 | 只看该作者
使用 printf 打印浮点数时,确实可能会遇到一些精度问题或显示问题,但这并不一定意味着存在bug

使用特权

评论回复
9
Amazingxixixi| | 2025-1-24 12:39 | 只看该作者
学习一下,提升技能,新年快乐

使用特权

评论回复
10
风凉| | 2025-1-25 02:00 | 只看该作者
这些问题通常是由于浮点数的表示和精度限制导致的

使用特权

评论回复
11
她已醉| | 2025-1-25 03:00 | 只看该作者
浮点数在计算机内部是以二进制形式表示的,某些十进制小数无法精确地用二进制小数表示,这可能导致打印时精度丢失。例如,当你尝试打印一个非常接近某个小数的浮点数时,可能会得到不正确的结果

使用特权

评论回复
12
春日负喧| | 2025-1-25 04:00 | 只看该作者
确保你使用正确的格式字符串 %f %lf 来打印浮点数。对于单精度浮点数(float),使用 %f;对于双精度浮点数(double)或长双精度浮点数(long double),使用 %lf

使用特权

评论回复
13
温室雏菊| | 2025-1-25 05:00 | 只看该作者
由于浮点数的内部表示和计算中的舍入误差,即使两个浮点数看起来应该相等,它们也可能在比较或打印时表现出微小的差异

使用特权

评论回复
14
故意相遇| | 2025-1-25 06:00 | 只看该作者
不同的编译器和平台可能对浮点数的处理方式略有不同,这可能导致在某些情况下打印出的结果不一致

使用特权

评论回复
15
西洲| | 2025-1-25 07:00 | 只看该作者
在需要高精度计算时,考虑使用定点数或整数进行计算,并在必要时进行转换

使用特权

评论回复
16
捧一束彼岸花| | 2025-1-25 08:00 | 只看该作者
使用 %.nf 格式指定打印的精度(n是小数位数),以控制打印的精度。例如,printf("%.6f", d); 将打印小数点后六位

使用特权

评论回复
17
将爱藏于深海| | 2025-1-25 09:00 | 只看该作者
在比较浮点数时,使用一定的容差范围来比较它们的近似相等性,而不是直接比较两个浮点数是否相等

使用特权

评论回复
18
失物招領| | 2025-1-25 10:00 | 只看该作者
虽然使用 printf 打印浮点数可能会遇到一些问题,但通过正确的格式字符串和适当的处理,大多数情况下都可以得到满意的结果

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

24

帖子

1

粉丝