2012-05-04 32 views
1

我想用Cpp在阶乘中找到零的数目。问题是当我使用真正的大数字时。模数真的很长(fmod)

#include <stdio.h> 
#include <math.h> 

long zeroesInFact(long n) 
{ 
long double fact=1; 
long double denominator=10.00; 
long double zero=0.0000; 
long z=0; 
printf("Strating loop with n %ld\n",n); 
for(int i=2;i<=n;i++) 
{ 
    fact=fact*i; 
    printf("Looping with fact %LF\n",fact); 
} 
printf("Fmod %lf %d\n",fmod(fact,denominator),(fmod(fact,denominator)==zero)); 
while(fmod(fact,denominator)==zero) 
{ 
    fact=fact/10; 
    z++; 
} 
printf("Number of zeroes is %ld\n",z); 
return z; 
} 

int main() 
{ 
long n; 
long x; 
scanf("%ld",&n); 
for(int i=0;i<n;i++) 
{ 
    scanf("%ld",&x); 
    printf("Calling func\n"); 
    zeroesInFact(x); 
} 
return 0; 
} 

我觉得这里的问题是,

FMOD(事实上,分母) 让我对22个因子和分母正确答案为10.00(即0.000)。 但它给了我一个错误的答案因为23和分母10.00

+2

提示:产品中零的数量与被乘数素数因子列表中的“5”和“2”的数量有关。 –

+1

没有。 11^5 = 161051。目前尚不清楚OP是否对'零点数'感兴趣,因为他说过或他真的想要'TRAILING零点数'。从他的代码看起来他想要第二个。 – fjardon

+0

也许[这个相关的讨论](http://stackoverflow.com/q/2847069/312172)对你很有意思。 –

回答

3

考虑这是你的第一课数值精度。类型float,doublelong double存储近似值,而不是精确值,这意味着它们通常不适合这种计算。即使它们具有足够的精度以获得正确的答案,您仍然可以更好地使用整数数字类型,例如int64_tuint64_t。有时甚至可以使用128位整数类型。 (例如,__int128可能与Microsoft Visual Studio一起提供)

老实说,我认为你很幸运能通过22!获得18!的正确答案。

如果long double真的在您的平台上具有四倍的精度,您应该能够计算出高达30!,我想。您在使用fmod时犯了错误 - 您的意思是使用fmodl


你的第二课精度是当你需要很多的时候,你的基本数据类型不够好。虽然您可以编写自己的数据类型,但最好使用预先存在的解决方案。算术库(GMP)是一个很好且快速的C/C++库。

或者,您可以切换语言 - 例如, python s整型数据类型是任意精度(但不像GMP那么快),所以你甚至不需要做任何特殊的事情。 Java有用于执行此类计算的BigInteger类。


你的第三课是精确的是想办法没有。您实际上并不需要计算23!的全部荣耀来找到尾随零的数量。小心,您可以组织您的计算来放弃您不需要的额外精度。或者,您可以切换到一个完全不同的方法来获取此号码,例如Rob在他的评论中暗示的内容。

+0

经验教训。谢谢:)我意识到我只需要5阶乘数 –