嘿,所有这些希望是一个简单的问题要回答,但这对我来说是全新的,我不知道它为什么会发生。使用以下 C ++ 代码:
template<class T>
T expo(T a, T b){
T result = 1;
while(b) {
if(b & 1)result *= a;
b >>=1 ;
a *= a;
}
return result;
}
int main() {
cout << std::pow<size_t>(50, 5) << endl;
cout << expo<size_t>(50, 5) << endl;
}
输出结果为:
3.125e+008
312500000
两者都是正确的,但std::pow()
将输出格式化为科学记数法。它是如何做到这一点的?我必须缺少 C ++ 的功能。救命啊!
答案 0 :(得分:3)
pow
的返回类型是double/float
,无论输入的类型是什么,expo
的返回类型是size_t
,因为编译器实例化了expo
} size_t
。
您可以使用std::fixed
将双重格式设置为非科学。
重要更新:
gcc中有pow
的模板库声明(我不确定它是否标准),它接受类型:
template<typename _Tp, typename _Up>
inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
pow(_Tp __x, _Up __y)
{
typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
return std::pow(__type(__x), __type(__y));
}
返回值为double/float
。
答案 1 :(得分:1)
所以基本答案是:
std::pow<size_t>(50, 5)
返回 double ,因此输出默认为 scientific 格式。如果我们查看 cppreference it claims上的文档,那么 C ++ 11 * integral *参数将转换为 double 和这些情况的输出应为 double 。我无法将标准中强烈的声明固定,但输出与该解释一致。
我们可以使用std::typeid确认至少double
和gcc
的输出确实为clang
:
std::cout << typeid( std::pow<size_t>(50, 5)).name() << std::endl;
当我们通过d
运行时输出c++filt -t d
,它告诉我们它是 double 。
更新
找到draft C++ standard中的相关部分。如果我们查看26
Numerics库部分,然后转到涵盖26.8
标题的<cmath>
C库部分,它会指定 float , double 和 long double 的数学函数的重载,其中包含 8 :
除了数学函数的双重版本之外,C ++还添加了这些函数的float和long double重载版本,具有相同的语义。
它涵盖 11 段落中的整数案例,其中说明了(强调我的):
此外,还应有足够的额外过载来确保:
- 如果对应于double参数的任何算术参数的类型为long double,则对应于double参数的所有算术参数都有效地转换为long double。
- 否则,如果对应于double参数的任何算术参数具有double类型或整数类型,则则对应于double参数的所有算术参数将被有效地转换为double。
- 否则,与double参数对应的所有算术参数都具有float。
类型 醇>