i want to print a 'double' variable upto 8 decimal places without trailing zeroes.

for eg:

if a= 10.1234 then print 10.1234
if a= 10.00 then print 10
if a= 10.11111111111 then print 10.11111111 (max of 8 decimal places).

how to do it?
i searched for it and found this:
printf("%g",a);
this work fine but print upto 6 decimal places.

Recommended Answers

All 5 Replies

Off the top of my head, I'm going to say that it's not possible to mix and match %f (which supports a precision) and %g (which has a zero removal rule). You'd need to use a less direct solution, such as sprintf() followed by a right trim of zeros.

From the Linux fprintf() man page:

   The flag characters
       The character % is followed by zero or more of the following flags:

       #      The value should be converted to an "alternate form".  For o conversions, the  first  character  of  the
              output  string  is  made zero (by prefixing a 0 if it was not zero already).  For x and X conversions, a
              non-zero result has the string "0x" (or "0X" for X conversions) prepended to it.  For a, A, e, E, f,  F,
              g,  and G conversions, the result will always contain a decimal point, even if no digits follow it (nor-
              mally, a decimal point appears in the results of those conversions only if a digit follows).  For g  and
              G  conversions,  trailing  zeros  are not removed from the result as they would otherwise be.  For other
              conversions, the result is undefined.

       0      The value should be zero padded.  For d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversions, the con-
              verted value is padded on the left with zeros rather than blanks.  If the 0 and - flags both appear, the
              0 flag is ignored.  If a precision is given with a numeric conversion (d, i, o, u, x, and X), the 0 flag
              is ignored.  For other conversions, the behavior is undefined.

       -      The converted value is to be left adjusted on the field boundary.  (The default is right justification.)
              Except for n conversions, the converted value is padded on the right with blanks,  rather  than  on  the
              left with blanks or zeros.  A - overrides a 0 if both are given.

       ' '    (a space) A blank should be left before a positive number (or empty string) produced by a signed conver-
              sion.

       +      A sign (+ or -) should always be placed before a number produced by a signed conversion.  By  default  a
              sign is used only for negative numbers.  A + overrides a space if both are used.

       The  five flag characters above are defined in the C standard.  The SUSv2 specifies one further flag character.

       '      For decimal conversion (i, d, u, f, F, g, G) the output is to be grouped with thousands’ grouping  char-
              acters  if  the  locale  information indicates any.  Note that many versions of gcc(1) cannot parse this
              option and will issue a warning.  SUSv2 does not include %'F.

       glibc 2.2 adds one further flag character.

       I      For decimal integer conversion (i, d, u) the output uses the locale’s alternative output digits, if any.
              For example, since glibc 2.2.3 this will give Arabic-Indic digits in the Persian ("fa_IR") locale.

   The field width
       An  optional  decimal  digit  string (with non-zero first digit) specifying a minimum field width.  If the con-
       verted value has fewer characters than the field width, it will be padded with spaces on the left (or right, if
       the  left-adjustment  flag  has been given).  Instead of a decimal digit string one may write "*" or "*m$" (for
       some decimal integer m) to specify that the field width is given in the next argument, or in the m-th argument,
       respectively,  which must be of type int.  A negative field width is taken as a '-' flag followed by a positive
       field width.  In no case does a nonexistent or small field width cause truncation of a field; if the result  of
       a conversion is wider than the field width, the field is expanded to contain the conversion result.

   The precision
       An optional precision, in the form of a period ('.')  followed by an optional decimal digit string.  Instead of
       a decimal digit string one may write "*" or "*m$" (for some decimal integer m) to specify that the precision is
       given in the next argument, or in the m-th argument, respectively, which must be of type int.  If the precision
       is given as just '.', or the precision is negative, the precision is taken to be zero.  This gives the  minimum
       number of digits to appear for d, i, o, u, x, and X conversions, the number of digits to appear after the radix
       character for a, A, e, E, f, and F conversions, the maximum number of significant digits for g  and  G  conver-
       sions, or the maximum number of characters to be printed from a string for s and S conversions.

   The length modifier
       Here, "integer conversion" stands for d, i, o, u, x, or X conversion.

       hh     A  following integer conversion corresponds to a signed char or unsigned char argument, or a following n
              conversion corresponds to a pointer to a signed char argument.

       h      A following integer conversion corresponds to a short int or unsigned short int argument, or a following
              n conversion corresponds to a pointer to a short int argument.

       l      (ell)  A following integer conversion corresponds to a long int or unsigned long int argument, or a fol-
              lowing n conversion corresponds to a pointer to a long int argument, or a following c conversion  corre-
              sponds to a wint_t argument, or a following s conversion corresponds to a pointer to wchar_t argument.

       ll     (ell-ell).   A  following  integer  conversion  corresponds to a long long int or unsigned long long int
              argument, or a following n conversion corresponds to a pointer to a long long int argument.

       L      A following a, A, e, E, f, F, g, or G conversion corresponds to a long  double  argument.   (C99  allows
              %LF, but SUSv2 does not.)

       q      ("quad". 4.4BSD and Linux libc5 only.  Don’t use.)  This is a synonym for ll.

       j      A following integer conversion corresponds to an intmax_t or uintmax_t argument.

       z      A  following  integer  conversion  corresponds to a size_t or ssize_t argument.  (Linux libc5 has Z with
              this meaning.  Don’t use it.)

       t      A following integer conversion corresponds to a ptrdiff_t argument.

Pay special attention to the "precision" and "field width" specs above.

Pay special attention to the "precision" and "field width" specs above.

No disrespect, but unless I'm misreading your post (in which case I apologise) you should follow your own advice. ;) The %f specifier doesn't remove trailing zeros when the precision exceeds the value, and the precision on the %g specifier affects significant digits rather than digits after the radix. So while %g can be used to get the correct behavior, that's only after doing introspection on the value to determine how many whole digits are present:

#include <stdio.h>
#include <math.h>

int main(void)
{
    double a = 1234.567891234;

    // Quick and dirty digit count
    int digits = log10((double)(int)a) + 1;

    printf("%.*g\n", 8 + digits, a);

    return 0;
}
commented: Good point - haven't had to deal with this cruft in 20 years! :-) +11

@deceptikon can you please explain the printf statement?

@deceptikon can you please explain the printf statement?

This is the point where I'll suggest that you RTFM, because format strings are clearly and completely described. But, I'll also explain it.

The %g specifier selects the behavior of either the %f or %e specifier (that's fixed or scientific format, respectively), depending on the actual value being printed. By default, if the exponent in your value exceeds 6 or -4, %g uses scientific format rather than fixed format. Trailing zeros are omitted, which is behavior you want (%f doesn't provide this).

When you provide a precision to the specifier (a dot followed by a numeric value), %g treats that as a maximum number of significant digits, which means both whole number digits and precision digits. For example, the value 123.456 has six significant digits. IF you try to print it with printf("%.4g", 123.456), you'll get 123.4 as output.

The numeric value in the precision can be a placeholder for an argument rather than a literal value in the string, that's what the asterisk does. It says "take the next argument to printf() and use that value as the precision". Another way of writing the example above using a placeholder would be printf("%.*g", 4, 123.456).

All in all, what my example does is calculate the number of digits in the whole value, then adds 8 to this (where 8 corresponds to the number of precision digits you want), then uses that value as the significant digits for the %g specifier. It simulates through value introspection the behavior of the precision for the %f specifier.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.