真的很长的数模量(FMOD)(Modulus of a really really long num

2019-07-29 06:26发布

我想找到使用cpp来的阶乘零数。 问题是,当我使用非常大的数字。

#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错误的答案

Answer 1:

考虑这一点您在数值精度的第一课。 类型floatdouble ,和long double商店近似值,而不是精确值,这意味着它们通常不适合用于这种计算的。 即使他们有足够的精度正确答案,你还是平时最好使用整数数字类型,而不是像int64_tuint64_t 。 有时候,你甚至连有一个可用的128位整数类型。 (如__int128可能会提供与Microsoft Visual Studio)

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

如果long double确实是四精度你的平台上,你应该能够计算高达30! , 我认为。 你犯了一个错误,当你使用fmod -你想用fmodl


在精密的第二个教训是,当你需要它的很多,你的基本数据类型根本就不够好。 虽然你可以写你自己的数据类型,你可能关闭使用预先存在更好的解决方案。 该牛羚多精度算术库(GMP)是一个很好的,快速的一个,你可以在C / C ++使用。

或者,您可以切换语言-如python小号整数数据类型的任意精度(但速度不如GMP),所以你甚至不必做任何特殊。 Java有BigInteger做这样的计算类。


你的第三个教训是精度是想办法不这样做。 你实际上并不需要计算23! 在其盛开找到尾随零的数目。 小心,你可以组织你的计算丢弃额外的精度就不需要。 或者,您可以切换到获得这个数,比如什么罗布在他的评论暗示完全不同的方法。



文章来源: Modulus of a really really long number (fmod)
标签: c++ range