25
votes

I am working on application which works on various flavors of Unix and Windows 32bit and 64bit OS.

I am using long double data type, When I do sprintf() and used long double with %lf in it then it works fine with windows does not give any kind of error, however on Solaris platform it gives core dump.

Sample code for the same issue is as following.

void main(){
    string size = "16622";
    string sizeFact = "20";
    long long sizeLongLong = strtoll(size);
    int factInt = atoi(sizeFact);
    long double sizeLongDouble = (long double) sizeLongLong/pow(2, factInt);
    char buf[512];
    sprintf(buf, "%.3lf %s", sizeLongDouble, "str");    
}

As mentioned above code works fine on windows 32bit and 64bit however for sprintf it gives me core on Solaris.

I tried type casting in sprintf it worked fine.

sprintf(buf, "%.3lf %s", (double) sizeLongDouble, "str");

What is the format specifier for long double?

What is the mistake I am making here, am I using wrong format specifier because of which it is giving core?

Why do I need to type cast one more time in sprintf()?

4

4 Answers

24
votes

For long double you should use format "%Lf". Formatting with small L (i.e. "%lf") have no effect on POSIX systems (see the specification).

3
votes

The documentation makes this pretty clear:

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

So, you should use %Lf.

1
votes

I would add this as a comment but I cannot do that yet. It is also important to note that you could also use the Exponential 'p' notation for long double in this way:

  • Fixed-point notation: %Lf
  • Exponential-notation: %Le
  • p notation: %La
0
votes

Depending on the compiler I have seen %Lf and %llf try both and see which works. The %lf that you use is the format specifier for double not for long double. I believe on g++ you should use %llf, while on visual studio it is %Lf.