Susanna
Susanna

Reputation: 771

Getting printf() to drop the trailing ".0" of values

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

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

Upvotes: 5

Views: 19470

Answers (6)

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 506837

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);
}

Upvotes: 2

plinth
plinth

Reputation: 49179

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...

Upvotes: 1

Dana the Sane
Dana the Sane

Reputation: 15198

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.

Upvotes: 1

Jason
Jason

Reputation: 2371

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.

Upvotes: 9

pajton
pajton

Reputation: 16226

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.

Upvotes: 0

Reed Copsey
Reed Copsey

Reputation: 564323

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?)

Upvotes: 0

Related Questions