Home > Software design >  Is there any effect of the length sub-specifier “l“ in the context of the (good) old printf?
Is there any effect of the length sub-specifier “l“ in the context of the (good) old printf?

Time:10-29

The question is about the (good) old printf function. The length sub-specifier "l" is documented in the table named "specifiers" in:

https://www.cplusplus.com/reference/cstdio/printf/

The cell for the explenation for the combination of the length sub-specifier “l“ with the specifiers "f F e E g G a A" is left blanck. Does this mean, that for example "%le" behaves always like "%e"? I tried hard to find an example where I get a difference between the "%le"-output and the "%e"-output … without any success. Can it be, that "%le" and "%e" produce generally the same output in the printf-context? I am using the Visual Studio Version 16.11.5 with the MSC-Version 19.29.30136 (MSC_FULL_VER is “192930136“). Here is my code:

#include <iostream>

//to get the MSC-compiler version
#define XSTR(x) STR(x)
#define STR(x) #x
#pragma message("_MSC_FULL_VER:")
#pragma message(XSTR(_MSC_FULL_VER))

int main()
{
    double d = 1.123456789123456789123456789;
    long double ld = static_cast<long double>(d);

    printf("%.20e\n" , d);
    printf("%.20le\n", d);
    printf("%.20le\n", ld);
    printf("%.20e\n" , ld);

    return 0;
}

And here is the corresponding output:

1.12345678912345681155e 00
1.12345678912345681155e 00
1.12345678912345681155e 00
1.12345678912345681155e 00

CodePudding user response:

The 2018 C standard says in clause 7.21.6.1, paragraph 7, for l:

… has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.

(Text elided to the “…” used above specifies the effects of l on other specifiers.)

CodePudding user response:

As already pointed out by Eric Postpischil, the length specifier l has no effect for the specifiers f F e E g G a A. Use the length specifier L for printing long double.

Note that some compilers (e.g. MSVC) will treat long double as if it is double.

The following code will generate different output if the compiler supports higher precession for long double:

#include <stdio.h>

int main()
{
    double d = 1.123456789123456789123456789;
    long double ld = 1.123456789123456789123456789L;

    printf("Double:      %.20e\n", d);
    printf("Long Double: %.20Le\n", ld);

    printf("Size of double:      %lu\n", sizeof(double));
    printf("Size of long double: %lu\n", sizeof(long double));

}

Output with clang 13.0.0 is the following:

Double:      1.12345678912345681155e 00
Long Double: 1.12345678912345678911e 00
Size of double:      8
Size of long double: 16
  • Related