5

I need to print floating point numbers with the following formatting requirements:

  • 5.12345 should display only 5.1

  • 5.0 should only 5 (without the .0)

  • 5.0176 should display only 5 (without the .01)

I thought printf() could do something like this... but now I can't seem to get it to work.

iHunter
  • 6,205
  • 3
  • 38
  • 56
Susanna
  • 771
  • 3
  • 10
  • 17
  • I think we'll need a more systematic description of the results you want. Right now, you've given a couple of examples, but I'm not at all sure what you'd want for (say) a value of 15.2. Do you want a maximum of 2 significant digits, or display only to the units place, or what exactly? – Jerry Coffin Mar 09 '10 at 19:28
  • What do you want in case of `5.06` ? Printf is likely to round it up to `5.1`. Do you want to drop the `.1` ? – Johannes Schaub - litb Mar 09 '10 at 19:54
  • Possible duplicate of [Avoid trailing zeroes in printf()](http://stackoverflow.com/questions/277772/avoid-trailing-zeroes-in-printf) – Jason C May 11 '16 at 07:12

6 Answers6

9

You can get kind of close to the results you want using "%g"

#include <stdio.h>

int main(int argc, char* argv[])
{
        printf("%.6g\n", 5.12345f);
        printf("%.6g\n", 5.0f);
        printf("%.6g\n", 5.0176f);
        return 0;
}

Output:

5.12345
5
5.0176

"%g" will remove trailing zeros.

Jason
  • 2,341
  • 17
  • 14
2

Sounds like you want to print 1 decimal place, and if that place is 0, drop it. This function should work fine:

// prints the float into dst, returns the number
// of chars in the manner of snprintf. A truncated
// output due to size limit is not altered.
// A \0 is always appended. 
int printit(float f, char *dst, int max) {
  int c = snprintf(dst, max, "%.1f", f);

  if(c > max) {
    return c;
  }

  // position prior to '\0'
  c--;

  while(dst[c] == '0') {
    c--;
    if(dst[c] == '.') {
      c--;
      break;
    }
  }
  dst[c + 1] = '\0';  
  return c + 1;
}

int main(void) {
  char num1[10], num2[10], num3[10];
  printit(5.12345f, num1, 10);
  printit(5.0f, num2, 10);
  printit(5.0176f, num3, 10);
  printf("%s\n%s\n%s\n", num1, num2, num3);
}
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
1

Not the way you've described it, no. If you want conditional decimal places, you have to do it yourself.

it's been a while since I've mucked with printf formats, but this appears to work in most cases

char *BuildConditionalFormat(double val)
{
    int tenths = (int)(val * 10) % 10;
    if (tenths == 0)
        return ".0f";
    return ".1f";
}

/* test rig */
float f = 5.0;
printf(BuildConditionalFormat(f), f); /* -> 5 */
f = 5.13;
printf("\n");
printf(BuildConditionalFormat(f), f); /* -> 5.1 */
printf("\n");

This abides by your rules, but will also provide an interesting lesson in why floating point stinks because 5.1 -> 5. Why? Because 5.1 doesn't represent cleanly (on my machine) as a float - it's 5.09999 and some more change.

Chances are you need to learn about floor() and ceil() too...

plinth
  • 48,267
  • 11
  • 78
  • 120
1

printf() can use formatting strings. Look at the width and precision options of the formatting strings:

printf("%.1f", 5.12345f);

This will print 5.1.

Unfortunately, it does not have the ability to automatically determine, without guidance, what to display. (For example, your last option there is unclear to me - why should it drop the ".0176", without you telling it you want no decimal points?)

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
1

None of the formatting operators support this, however you could filter the float through sprintf() first, then truncate the string where appropriate. This saves you the trouble of converting the float to a string and the logic to do the rest is easy.

Dana the Sane
  • 14,762
  • 8
  • 58
  • 80
  • One issue with this is that it doesn't easily support rounding, if that is desirable. In the original post, none of the examples show anything that would need to be rounded up, so we don't know if that is a requirement or not. – Jon Oct 19 '16 at 21:14
0

You can tell printf to print specified number of digits after '.' ,but if you want to differ the format basing on the value you have to write code to distinguish cases interesting for you.

pajton
  • 15,828
  • 8
  • 54
  • 65