我正在编写一个函数,我必须计算数字的阶乘并对它们进行操作。函数的返回值应该很长,所以我认为以long long格式执行所有操作会更好。如果我错了,请纠正我。
tgamma()函数本身以科学计数形式返回正确的值。但是当函数返回的值被强制转换为'long long'时,tgamma()返回的值有时比实际答案少1。
int main()
{
std::cout<<"11!:"<<tgamma(12)<<std::endl;
std::cout<<"12!"<<tgamma(13)<<std::endl;
std::cout<<"13!"<<tgamma(14)<<std::endl;
std::cout<<"14!"<<tgamma(15)<<std::endl;
std::cout<<"15!"<<tgamma(16)<<std::endl;
std::cout<<"16!"<<tgamma(17)<<std::endl;
std::cout<<"********************************"<<std::endl;
std::cout<<"11!:"<<(long long)tgamma(12)<<std::endl;
std::cout<<"12!"<<(long long)tgamma(13)<<std::endl;
std::cout<<"13!"<<(long long)tgamma(14)<<std::endl;
std::cout<<"14!"<<(long long)tgamma(15)<<std::endl;
std::cout<<"15!"<<(long long)tgamma(16)<<std::endl;
std::cout<<"16!"<<(long long)tgamma(17)<<std::endl;
return 0;
}
我得到以下输出:
11!:3.99168e+07
12!4.79002e+08
13!6.22702e+09
14!8.71783e+10
15!1.30767e+12
16!2.09228e+13
********************************
11!:39916800
12!479001599
13!6227020799
14!87178291199
15!1307674367999
16!20922789888000
实际值15!根据{{3}}是1307674368000,但是当我将tgamma(16)强制转换为long long时,我得到的只是1307674367999.事情是这种差异只出现在一些数字上。 16的答案!是正确的 - 20922789888000。
此功能适用于目前正在进行的竞争性编程问题,因此我无法在此处粘贴我正在开发的功能和解决方案。
我会推出自己的阶乘函数,但我希望减少程序中的字符数以获得奖励积分。
有关如何检测类型差异并纠正错误的任何提示?或者也许我可以使用其他一些功能?
答案 0 :(得分:0)
从浮点类型转换为整数类型截断。尝试(long long) roundl(tgammal(xxx))
摆脱整数截断错误。这也是使用长双打,所以它可以给你更多的数字。
#include <math.h>
#include <iostream>
int main(){
std::cout<<"11!:"<<(long long)roundl(tgammal(12))<<std::endl;
std::cout<<"12!"<<(long long)roundl(tgammal(13))<<std::endl;
std::cout<<"13!"<<(long long)roundl(tgammal(14))<<std::endl;
std::cout<<"14!"<<(long long)roundl(tgammal(15))<<std::endl;
std::cout<<"15!"<<(long long)roundl(tgammal(16))<<std::endl;
std::cout<<"16!"<<(long long)roundl(tgammal(17))<<std::endl;
std::cout<<"********************************"<<std::endl;
std::cout<<"11!:"<<(long long)roundl(tgammal(12))<<std::endl;
std::cout<<"12!"<<(long long)roundl(tgammal(13))<<std::endl;
std::cout<<"13!"<<(long long)roundl(tgammal(14))<<std::endl;
std::cout<<"14!"<<(long long)roundl(tgammal(15))<<std::endl;
std::cout<<"15!"<<(long long)roundl(tgammal(16))<<std::endl;
std::cout<<"16!"<<(long long)roundl(tgammal(17))<<std::endl;
return 0;
}
给出:
11!:39916800
12!479001600
13!6227020800
14!87178291200
15!1307674368000
16!20922789888000
********************************
11!:39916800
12!479001600
13!6227020800
14!87178291200
15!1307674368000
16!20922789888000
答案 1 :(得分:0)
显然,除非我们有非常不寻常的实现,否则不是所有的长数都可以精确地表示为double。因此,tgamma不能存储双精度值,以便铸造成long long会产生精确值。在很长的时间间隔内,只需要比长值更长的长值。
如果你想要精确的long long factorial,你应该自己实现它。
除此之外,如果你想要精度,你可以将double变换为long long而不是(long long)x,但是(long long)round(x)或(long long)(x + 0.5),假设x是正面的。