-3

Consider the following code snippet:

char str[1000];
float b ;
b= 0.0615;
sprintf( &(str[0]), "%1.0e", b);

After the execution of the last statement, I expected the str to contain 6.15e-2. However, I am getting the value as 5e-315.

Where am I going wrong. How to get the expected value?

nitin_cherian
  • 6,405
  • 21
  • 76
  • 127
  • I'm getting 6e-002 on gcc – phuclv Jun 24 '14 at 08:47
  • 4
    [Cannot reproduce](http://ideone.com/8HwFys). – Kerrek SB Jun 24 '14 at 08:48
  • 2
    Are you sure you are actually assigning the value to the variable? Your code example looks like it was copy-pasted from separate parts of the program, so maybe your real code is missing the assignment. – Kerrek SB Jun 24 '14 at 08:52
  • The problem, is general, is undefined behavior as the proper prototype from `stdio.h` did not occur. It _is_ reproducible, albeit in a strange fashion, if the `float` is not promoted to `double` and 4 zero bytes area appended. With `.0615` as a `double`, the 8 bytes `3faf7ceda0000000` _should_ have been passed. Instead `000000003faf7ced` was passed and the result of `5e-315` was received by `printf()`. – chux - Reinstate Monica Jun 25 '14 at 00:20

3 Answers3

1

You cannot get two digits precision with that format string, as you specified only one digit after comma (that is the .0 part after the 1).

What works for me is

#include <stdio.h>
#include <string.h>

main() {
    char str[1000];
    float b ;
    b= 0.0615;
    sprintf( &(str[0]), "%.2e", b);
    puts(str);
}

prints 6.15e-02

The almighty C/C++ documentation says:

.number:

For a, A, e, E, f and F specifiers: this is the number of digits to be printed after the decimal point (by default, this is 6).

jcklie
  • 4,054
  • 3
  • 24
  • 42
  • You are linking to the "almighty" ***C++*** documentation. – undur_gongor Jun 24 '14 at 09:34
  • I knew somebody would say that, so I edited it for you. The format itself is the same for both languages. – jcklie Jun 24 '14 at 09:35
  • "C(++)" is a new syntax I haven't seen yet. Will it compete with the venerable "C/C++", or the new-comer "C\C++"? – Kerrek SB Jun 24 '14 at 10:09
  • I considered C(++)? - escaped, it would look really ugly, like C(\+\+)? - for the regex geeks, as I am one, but I edit it to the oldie but goldie C/C++. – jcklie Jun 24 '14 at 10:14
1

My bet is you forgot including stdio.h.

There seems to be a mismatch between what type the compiler passes to sprintf and what sprintf actually reads (as described in cmaster's answer).

Community
  • 1
  • 1
undur_gongor
  • 15,657
  • 5
  • 63
  • 75
  • 1
    That sounds unlikely beyond belief. Since `sprintf` has an ellipsis argument, it can only ever expect `double` arguments, and `float` never. – Kerrek SB Jun 24 '14 at 10:08
  • @KerrekSB: You are right. I got it wrongly. Still I think the reason is the missing include. – undur_gongor Jun 24 '14 at 10:27
0

Apparently your compiler does not realize that sprintf() takes all floating point arguments as doubles. Consequently, it passes only the 32 bits of the float to the function, which erroneously interpretes 64 bits as a double. It should work fine if you cast the float to a double before passing it to sprintf().

cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106
  • that would violate C standard, I've never seen any compilers like that – phuclv Jun 24 '14 at 13:22
  • @LưuVĩnhPhúc But it explains precisely the observed behaviour. Probably the OP also forgot to include the `stdio.h` header, triggering implicit definition of `sprintf()` as `int sprintf();`. – cmaster - reinstate monica Jun 26 '14 at 08:45
  • but without prototype (due to forgetting the include) the compiler will assume that function uses [default arguments rule](http://stackoverflow.com/questions/1255775/default-argument-promotions-in-c-function-calls) in which floats are always promoted to double – phuclv Jun 26 '14 at 09:33
  • @LưuVĩnhPhúc Ah, thanks for the link, I wasn't aware of these details. I never use the default argument rule, you know... So, yes, we can conclude that if my answer is the correct one, then the compiler is broken. But I wouldn't put it past a special compiler to not conform to the standard perfectly. Consequently, I still believe that this answer is correct, even though it is just an educated guess at what's happening. – cmaster - reinstate monica Jun 26 '14 at 12:28