8

I am writing a C program for SAM3N arm cortex-M3 microcontroller. When I try to print float numbers, it just prints 'f'. Example: printf("%f",43.12); prints f only, not the 43.12.

But printing with integers works fine.

How to enable full printing of floats? I know that the compiler, by default, disabled float printing to reduce code size (i.e. seems, they linked cut-down version). Also please note that, there is no CFLAGS=-Dprintf=iprintf used in makefile.

Tools details:

  • ARM/GNU C Compiler : (crosstool-NG 1.13.1 - Atmel build: 13) 4.6.1
  • Above tool come with Atmel studio 6.0.
unwind
  • 391,730
  • 64
  • 469
  • 606
Prabhu U
  • 304
  • 1
  • 4
  • 9
  • AFAIK this microcontroller is has no FPU. So you need to refer to compiler documentation to libc how to enable full printf capability. For example on AVR it was "-Wl,-u,vfprintf -lprintf_flt -lm". Another way, you should contact your tools vendor perhaps it is known issue. – Sergei Nikulov Oct 03 '12 at 07:35
  • Unfortunately, this -lprintf works only for AVR-GCC, but NOT for ARM. – Prabhu U Oct 03 '12 at 08:34

4 Answers4

11

Can you try, adding the below option in linker settings

-lc -lrdimon -u _printf_float

and it worked for me in ARM-CORTEXM0

4

It can be so that your platform/libs does not support %f format specifier for printf/sprintf. As a first approach you can roll your own printf for floats/doubles:

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);
}
mrUnfused
  • 45
  • 1
  • 7
Agnius Vasiliauskas
  • 10,935
  • 5
  • 50
  • 70
  • Thanks for the idea, but I already implemented this as a work around (using modf, lround). And I wanted proper printf so that code will be cleaner. – Prabhu U Oct 03 '12 at 08:32
1

The answer of @Agnius Vasiliauskas is partially correct; however, it doesn't consider the case when v is negative and greater than -1 (-1<v<0) in fact in that situation the intPart should have a minus sign ahead.

For example: if is v=-0.55 intPart will be 0, so you will print 0.55 and not -0.55! You have to add the correct sign manually, as shown below.

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);
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Lisa
  • 11
  • 2
0

In compilers where floats are disabled by default, it is unusual that the default libraries can handle them. Look through your references and you will find information on how to recompile the appropriate libraries with float support, or (more likely) where to find a version that has already been built with it.

Sniggerfardimungus
  • 11,583
  • 10
  • 52
  • 97
  • This is exactly where I am stuck. Seems, I need to replace libc by some other C library. Seems, default libc does not have printf that can printf floats. Any help/suggestion om how I can make it? – Prabhu U Oct 03 '12 at 08:44
  • It is the library that doesn't support printfing floats right - gcc shouldn't care about that? If you are looking for a different libc, try newlib, http://sourceware.org/newlib/ – auselen Oct 03 '12 at 11:33