【问题标题】:What's the correct way to sprintf a float?sprintf浮动的正确方法是什么?
【发布时间】:2010-12-02 16:50:34
【问题描述】:

我正在尝试使用此代码打印 f/sprintf 浮点数:

sprintf(buff, "FPS: %d\n%.4f N %.4f E\nAl: %.1fm Rl: %.1f\n", fps, p_viewer.p.lat, p_viewer.p.lon, p_viewer.p.alt, p_viewer.roll);

但是当我这样做时会收到这些警告:

gfx_game_engine.c:300: warning: format '%.4f' expects type 'double', but argument 4 has type 'float'
gfx_game_engine.c:300: warning: format '%.4f' expects type 'double', but argument 5 has type 'float'
gfx_game_engine.c:300: warning: format '%.1f' expects type 'double', but argument 6 has type 'float'
gfx_game_engine.c:300: warning: format '%.1f' expects type 'double', but argument 7 has type 'float'

sprintf 浮点数的正确方法是什么?有特殊格式字符吗?我觉得编译器可能会以某种方式强制转换类型,这可能会导致它变慢。

我正在使用 dsPIC33FJ128GP802 微控制器并使用 MPLAB C30(GCC v3.23 的变体)进行编译。

【问题讨论】:

  • %f 是 float %lf double 和 %Lf long double。你用的是什么编译器?
  • 如果您担心导致运行缓慢的原因,请对其进行分析。
  • @Let_Me_Be GCC (v3.23) 用于 dsPIC33F。 (也称为 Microchip MPLAB C30。)
  • @Nathon 像我这样的小型微控制器几乎没有基本的调试功能,忘记配置文件吧!
  • @Let_Me_Be:根据我来自 glibc6 的 sprintf 手册页,fF 都是双倍的。

标签: c floating-point printf


【解决方案1】:

您的 gcc 变体已损坏。在 C 语言中,无法将float 传递给可变参数函数。小类型的默认促销(charshortfloat)始终适用于至少 int/double。我猜想为这个微控制器破解 gcc 的人做了一些事情来禁用促销,可能是因为double 很慢或很难通过。你应该把他们烧到地狱然后回来。如果编译器供应商不想正确支持double,正确的解决方案是让所有浮点类型大小相同并等效于float,不要违反语言的提升规则。

另一个想法:sprintf 的原型也可能丢失或错误,例如 int sprintf(); 而不是 int sprintf(char *, const char *, ...);

【讨论】:

  • 总是在 GCC for Linux 上通过浮点数,并且在 32 位和 64 位系统上都没有遇到过问题,尽管我总是使用 GCC >=4,不是 GCC 3.23。
  • @Thomas:当您“将 float”“传递给可变参数函数”时,它会自动提升为 double 并以双精度形式传递。这种行为是 C 语言所要求的。
  • 它最终是什么问题?感谢您接受我的回答,但我很好奇。 :-)
【解决方案2】:

float 参数应自动​​转换为double。似乎没有其他方法可以打印float。在这种情况下,您的编译器不应该抱怨。

【讨论】:

    【解决方案3】:

    scanf 不同,其中%f 表示float,%lf 表示double,printf 不区分它们。因此,如果printf(或其变体)是通过库链接实现的,编译器将不得不进行转换。

    【讨论】:

      猜你喜欢
      • 2021-12-30
      • 1970-01-01
      • 2010-12-11
      • 2014-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 2011-12-01
      相关资源
      最近更新 更多