如果输入n = 6,则此代码返回719
int main()
{
long n,k;
cin>>n;
k = tgamma(n+1);
cout<<k;
}
虽然下面的代码将返回正确答案720
int main()
{
long n,k;
n=6;
k = tgamma(n+1);
cout<<k;
}
为什么会这样?
我使用cpp.sh进行测试
答案 0 :(得分:1)
std :: tgamma 根据cppreference 在需要很长时间后返回双。而且, double to long 转换可能会受到精度损失的影响。
这就是我拆卸程序所得到的。看起来编译器已经完成了一项魔术(技术上称为优化)。
左边的程序是第一个,右边的程序是第二个。
程序2第33行:编译器已完成计算以找到tgamma(6 + 1)
的值为720.编译器实际应用了该值并简化了表达式。
程序2第42行: [cvtsi2sdq] 将双字整数转换为标量双精度浮点值的汇编级指令
程序2第44行: [cvttsd2siq] 将标量双精度浮点值转换为带截断的带符号双字整数的汇编级指令
第二次提到的转换应该导致类型转换精度损失,导致意外值719(例如,从719.9299328截断)。
SPOILER:只需使用双长就可以避免此错误。