I find myself often entering in the wrong formatting type, and not remembering when to do f
or Lf
or lf
, etc. Is there a way to do something like the following with the help of the _Generic
keyword?
#define TYPE(X) _Generic((X), float: "float", double: "double", long double: "long_double")
#define FORMAT(X) _Generic((X), float: "%f", double: "%f", long double: "%Lf")
printf("%s if of type %s\n", FORMAT(10.), 10., TYPE(10.));
Basically, I want it to print:
10.000000 is of type double
Is there a way to do that?
I suppose one shorthand option would be doing something like:
#define TYPE(X) _Generic((X), float: "float", double: "double", long double: "long_double")
#define STRINGIZE(X) #X
printf("%s if of type %s\n", STRINGIZE(10.), TYPE(10.));
- if of type double
Format specifiers in printf
can't be made parameters by themselves. They need to be part of the format string.
You can do this by making the FORMAT
macro the entire format string for one call to printf
just to print the value. Then you can have another call for the rest:
printf(FORMAT(10.), 10.);
printf(" is of type %s\n", TYPE(10.));
But, as was stated in the comments, modern compilers are smart enough to detect mismatches between printf
format strings and their arguments. So relying on that works just as well.
wrong formatting type, and not remembering when to do f or Lf or lf, etc.
Note that for float
and double
, l
or not l
are valid as float
augments to a ...
parameter are promoted to double
. The l
is optional with printf
specifier "%f"
, and friends: fFeEgGaA
.
printf("%f\n", 1.2f);
printf("%f\n", 3.4);
printf("%lf\n", 5.6f); // unusual, yet OK
printf("%lf\n", 7.8);
To use _Generic
for printing, perhaps Formatted print without the need to specify type matching specifiers using _Generic .
A useful reason to use different print specifiers for float/double
is precision.
#define ForD(X) _Generic((X), float: FLT_DECIMAL_DIG-1, double: DBL_DECIMAL_DIG-1)
printf("%.*e\n", ForD(f), f); // Best if `f` is not be an expression.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.