21

I'm trying to work out why a larger problem is occurring, using a smaller program as an example. This smaller program does not work, leading me to believe it is my understanding of the function that is flawed.

As far as I (had) believed, the following program should initialise a string with up to 30 characters, then take the number '5' to nine significant figures, and turn it into that string. The program should then print the value '5.00000000'. However, the program prints the value 7.96788(...). Why is this?

#include <stdio.h>

int main()
{
    char word[30];
    sprintf(word, "%.9g", 5);
    printf(word);
    return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CaptainProg
  • 5,610
  • 23
  • 71
  • 116

4 Answers4

22

This is because 5 is an integer (int), and you're telling sprintf to pretend that it's a double-precision floating-point number (double). You need to change this:

sprintf(word,"%.9g", 5);

to either of these:

sprintf(word,"%.9g", 5.0);
sprintf(word,"%.9g", (double) 5);
ruakh
  • 175,680
  • 26
  • 273
  • 307
  • Pardon if it's obvious, but what does the `g` mean in `%.9g`? – CodyBugstein Dec 08 '13 at 15:52
  • 1
    @Imray: It's not exactly obvious, but the answer won't make sense without a general understanding of format strings. I recommend reading through either [the relevant part of the POSIX spec](http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html) or [the Wikipedia article](https://en.wikipedia.org/wiki/Printf_format_string). – ruakh Dec 08 '13 at 18:30
1

Use 5.0 instead. 5 by itself is an integer and will get bitmangled into looking like a float, which is where your 7.xxxx comes from.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Marc B
  • 356,200
  • 43
  • 426
  • 500
1

I see two problems:

  1. As others already said, you have to specify a double instead of an int. Your compiler may have a switch to print out warnings in these cases (-Wall in gcc, for example).

  2. To print out 5.00..., you should use %f instead of %g.

That gives sprintf(word,"%.9f", (double) 5); as correct syntax.

Dennis
  • 14,264
  • 2
  • 48
  • 57
  • 1
    In my experience very few compilers have such a warning; GCC is the only one I know of. Specifically the option is `-Wformat`, `-Wall` would be my recommendation too, but switches on other warnings. Also on older versions of GCC `-Wall` does not include `-Wformat`. – Clifford Nov 22 '11 at 19:50
  • *Most* compilers might have been an exaggeration. Fixed. For the record, icl also warns about this. – Dennis Nov 22 '11 at 19:57
0

Or you can change the descriptor format: "%.9d"

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131