真的很长的模数(fmod) [英] Modulus of a really really long number (fmod)

查看:96
本文介绍了真的很长的模数(fmod)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用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);
for(int i = 2; i< = n; i ++)
{
fact = fact * i;
printf(Looping with fact%LF \\\
,fact);
}
printf(Fmod%lf%d \\\
,fmod(fact,denominator),(fmod(fact,denominator)== zero)
while(fmod(fact,denominator)== 0)
{
fact = fact / 10;
z ++;
}
printf(0的数量为%ld \\\
,z);
return z;
}

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

我认为这里的问题是



fmod(fact,denominator)
给出了22的正确答案和分母为10.00的正确答案(0.000)。
但是它给出了阶乘23和分母为10.00的错误答案。

解决方案

数值精度。类型 float double long double ,而不是精确的值,这意味着它们通常不适合这种计算。即使他们有足够的精确度的正确答案,你仍然通常最好使用整数数字类型,如 int64_t uint64_t 。有时你甚至有一个128位整数类型可用。 (例如 __ int128 可能在Microsoft Visual Studio中可用)



老实说,我想你很幸运得到了权利


$ b

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






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



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






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


I want to find the number of zeroes in a factorial using Cpp. The problem is when I use really big numbers.

#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;
}

I think the problem here is that

fmod(fact,denominator) gives me the correct answer for factorial of 22 and denominator as 10.00 (which is 0.000). But it gives me the wrong answer for factorial of 23 and denominator as 10.00

解决方案

Consider this your first lesson in numeric precision. The types float, double, and long double store approximations, not exact values, which means they are typically unsuitable for this sort of calculation. Even when they have enough precision for correct answers, you're still usually better off using integer numeric types instead, like int64_t and uint64_t. Sometimes you even even have a 128-bit integer type available. (e.g. __int128 might be available with Microsoft Visual Studio)

Honestly, I think you were lucky to get the right answer for 18! through 22!.

If long double truly is quadruple precision on your platform, you should be able to compute up to 30!, I think. You made a mistake when you used fmod -- you meant to use fmodl.


Your second lesson in precision is that when you need a lot of it, your basic data types simply aren't good enough. While you can write your own data types, you're probably better off using a pre-existing solution. The Gnu Multiple Precision Arithmetic Library (GMP) is a good, and fast one you can use in C/C++.

Alternatively, you could switch languages -- e.g. pythons integer data type is arbitrary precision (but not as fast as GMP), so you wouldn't even have to do anything special. Java has the BigInteger class for doing such computations.


Your third lesson is precision is to find ways to do without. You don't actually need to compute 23! in its full glory to find the number of trailing zeroes. With care, you can organize your calculation to discard extra precision you don't need. Or, you can switch to an entirely different method of obtaining this number, such as what Rob was hinting at in his comment.

这篇关于真的很长的模数(fmod)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆