Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why wasn't a specifier for `float` defined in `printf`?

It looks like it could have been, there are (at least in C99) length modifiers that can be applied to int: %hhd, %hd, %ld and %lld mean signed char, short, long and long long. There is even a length modifier applicable to double: %Lf means long double.

The question is why did they omit float? Following the pattern, it might have been %hf.

like image 926
skyking Avatar asked Sep 11 '15 07:09

skyking


People also ask

What is %d %f %s in C?

%s refers to a string %d refers to an integer %c refers to a character. Therefore: %s%d%s%c\n prints the string "The first character in sting ", %d prints i, %s prints " is ", and %c prints str[0].

Can I use %F for double in C?

We can print the double value using both %f and %lf format specifier because printf treats both float and double are same. So, we can use both %f and %lf to print a double value.


Video Answer


1 Answers

Because in C variadic function calls, any float argument is promoted (i.e. converted) to a double, so printf is getting a double and would use va_arg(arglist, double) to get it inside its implementation.

In the past (C89 and K&R C) every float argument was converted to a double. The current standard omits this promotion for fixed arity functions which have an explicit prototype. It is related to (and details are explained in) the ABI & calling conventions of the implementation. Practically speaking, a float value would be often loaded into a double-floating point register when passed as an argument, but details can vary. Read the Linux x86-64 ABI specification as an example.

Also, there is no practical reason to give a specific format control string for float since you can adjust the width of the output (e.g. with %8.5f) as wanted, and %hd is much more useful (nearly necessary) in scanf than in printf

Beyond that, I guess that the reason (to omit %hf specifying float -promoted to double in caller- in printf) is historical: at first, C was a system programming language, not an HPC one (Fortran was preferred in HPC perhaps till the late 1990s) and float was not very important; it was (and still is) thought of like short, a way to lower memory consumption. And today's FPUs are fast enough (on desktop or server computers) to avoid using float except as a mean to use less memory. You basically should believe that every float is somewhere (perhaps inside the FPU or the CPU) converted to double.

Actually, your question might be paraphrased as : why %hd exists for printf (where it is basically useless, since printf is getting an int when you pass it some short; however scanf needs it!). I don't know why, but I imagine than in system programming it might be more useful.

You could spend time lobbying the next ISO C standard to get %hf accepted by printf for float (promoted to double at printf calls, like short-s get promoted to int), with undefined behavior when the double precision value is out of bound for float-s, and symetrically %hf accepted by scanf for float pointers. Good luck on that.

like image 144
Basile Starynkevitch Avatar answered Sep 17 '22 23:09

Basile Starynkevitch