So the basic answer is that:
std::pow<size_t>(50, 5)
is returning a double and therefore the output is defaulting to scientific format. If we look at the documentation on cppreference it claims the since C++11 *integral* arguments are cast to double and the output for these cases should be double. I am having trouble pinning that strong a statement from the standard but the output is consistent with that explanation.
We can confirm that the output is indeed double
for at least gcc
and clang
using std::typeid:
std::cout << typeid( std::pow<size_t>(50, 5)).name() << std::endl;
which output d
when we run that through c++filt -t d
it tells us that it is double.
Update
Found the relevant section in the draft C++ standard. If we look in section 26
Numerics library and then go to section 26.8
C library which covers the <cmath>
header, it specifies overloads of the math functions for float, double and long double which is covered in paragraph 8:
In addition to the double versions of the math functions in , C++ adds float and long double overloaded versions of these functions, with the same semantics.
and it covers the integral cases in paragraph 11 which says(emphasis mine):
Moreover, there shall be additional overloads sufficient to ensure:
- If any arithmetic argument corresponding to a double parameter has type long double, then all arithmetic arguments corresponding to double parameters are effectively cast to long double.
- Otherwise, if any arithmetic argument corresponding to a double parameter has type double or an integer type, then all arithmetic arguments corresponding to double parameters are effectively cast to double.
- Otherwise, all arithmetic arguments corresponding to double parameters have type float.