std::p ow() 输出是..特殊
std::pow() output is... special?
嘿,希望所有这些都是一个简单的问题,但这对我来说是全新的,我不知道为什么会发生这种情况。采用以下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++的特征。帮助!
无论
输入的类型是什么,pow
的返回类型都是double/float
的,expo
的返回类型是size_t
的,因为编译器为size_t
实例化expo
。您可以使用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
。
所以基本的答案是:
std::pow<size_t>(50, 5)
返回双精度,因此输出默认为科学格式。如果我们查看有关 cppreference 的文档,它声称自 C++11 *积分* 参数被转换为双倍,并且这些情况的输出应该是双倍。我很难从标准中固定出如此强烈的声明,但输出与该解释一致。
我们可以确认输出确实至少double
了 gcc
次,并且使用 std::typeid clang
:
std::cout << typeid( std::pow<size_t>(50, 5)).name() << std::endl;
当我们运行该输出时d
哪个输出c++filt -t d
它告诉我们它是双倍的。
更新
在C++标准草案中找到了相关部分。如果我们查看第 26
节 Numerics 库,然后转到涵盖 <cmath>
标头的第 26.8
C 库部分,它指定了第8 段中涵盖的浮点数、双精度数和长双精度数的数学函数的重载:
除了 中数学函数的双重版本之外,C++还添加了这些函数的浮点数和长双重载版本,具有相同的语义。
它涵盖了第11段中的整体情况,其中说(强调我的):
此外,还应有额外的超载,足以确保:
如果对应于双精度参数的任何算术参数具有长双精度
- 类型,则对应于双精度参数的所有算术参数都将有效地转换为长双精度。
否则,如果对应于双精度参数的任何算术参数- 具有双精度类型或整数类型,则对应于双精度参数的所有算术参数都将有效地转换为双精度。
- 否则,对应于双精度参数的所有算术参数都具有浮点类型。
相关文章:
- 递归函数计算序列中的平方和(并输出过程)
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 请解释"函数1(p1,p2,p3);"的输出
- C++:将控制台输出存储在宏中更好吗
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 为什么我的代码在输出中增加了93天
- 如何从void函数输出字符串
- 输入到文件并输出到另一个文件,并将流文件传递给函数
- AES加密到解密未正确输出
- 如何将c++程序的一些输出传递给shell,以便在shell中使用
- 如何用转义符替换字符串中的所有特殊字符
- 使用C++程序合并排序没有得到正确的输出
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- C++格式化输出问题
- 将值从二维数组输出到文本文件
- 带有特殊字符的字符串的控制台输出
- std::p ow() 输出是..特殊
- 带有输出长度限制和特殊参数的c++排列