arm-none-eabi-gcc:使用printf打印浮点数

8
我正在为SAM3N arm cortex-M3微控制器编写C程序。当我尝试打印浮点数时,它只会打印出'f'。 例如:printf("%f",43.12); 只打印f,而不是43.12
但是使用整数打印正常。
如何启用完整打印浮点数?我知道编译器默认禁用浮点数打印以减少代码大小(即似乎他们链接了精简版本)。还请注意,makefile中没有使用CFLAGS=-Dprintf=iprintf
工具详细信息: ARM/GNU C编译器:(crosstool-NG 1.13.1 - Atmel构建:13)4.6.1 以上工具随附于Atmel studio 6.0。

据我所知,这个微控制器没有FPU。因此,您需要参考编译器文档来了解如何启用完整的printf功能。例如,在AVR上,它是“-Wl,-u,vfprintf -lprintf_flt -lm”。另一种方法是,您应该联系您的工具供应商,也许这是一个已知的问题。 - Sergei Nikulov
不幸的是,这个-lprintf只适用于AVR-GCC,而不适用于ARM。 - Prabhu U
4个回答

11

你可以尝试在链接器设置中添加以下选项:

-lc -lrdimon -u _printf_float

并且我在ARM-CORTEXM0上这样做是有效的。


同样适用于ARM Cortex-M4。 - Bence Kaulics
“-lrdimon” 是用来做什么的?它似乎在我的应用程序中引起了不良反应。 - theorifice
“-lrdimon”是不必要的,并且会导致一些奇怪的行为。我从来不确定这个标志的影响是什么... - theorifice
备选数据点:在我的情况下,printf调用没有-lrdimon参数会崩溃。 - KT.

4

有时候你的平台或库可能不支持 %f 格式说明符用于 printf/sprintf 函数。 作为第一种方法,你可以自己编写格式化浮点数/双精度数的 printf 函数:

void printDouble(double v, int decimalDigits)
{
  int i = 1;
  int intPart, fractPart;
  for (;decimalDigits!=0; i*=10, decimalDigits--);
  intPart = (int)v;
  fractPart = (int)((v-(double)(int)v)*i);
  if(fractPart < 0) fractPart *= -1;
  printf("%i.%i", intPart, fractPart);
}

谢谢你的建议,但我已经使用modf和lround实现了这个解决方法。我想要一个正确的printf,这样代码会更加清晰。 - Prabhu U

1

@Agnius Vasiliauskas的答案部分正确;然而,它没有考虑v为负且大于-1(-1<v<0)的情况。实际上,在这种情况下,intPart应该在前面加上负号。

例如:如果v=-0.55,则intPart为0,因此您将打印0.55而不是-0.55!您必须手动添加正确的符号,如下所示。

void printDouble(double v, int decimalDigits)
{
  int i = 1;
  int intPart, fractPart;
  for (;decimalDigits!=0; i*=10, decimalDigits--);
  intPart = (int)v;
  fractPart = (int)((v-(double)(int)v)*i);
  if(fractPart < 0) fractPart *= -1;

  if(v<0 && intPart=0) printf("-%i.%i", intPart, fractPart);
  else printf("%i.%i", intPart, fractPart);
}

0
在默认情况下禁用浮点数的编译器中,通常默认库无法处理它们。请查阅您的参考资料,您会找到有关如何重新编译具有浮点支持的适当库的信息,或者(更可能)在哪里找到已经构建了该支持的版本。

这正是我卡住的地方。看起来,我需要用其他C库替换libc。似乎默认的libc没有能够打印浮点数的printf函数。有什么帮助或建议吗? - Prabhu U
这是一个不支持浮点数printf的库 - gcc不应该关心这个问题吧?如果你正在寻找另一个libc,可以尝试newlib,http://sourceware.org/newlib/。 - auselen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接