fmodl - 长双模数

时间:2013-08-30 13:09:27

标签: c++ math floating-point modulus exponentiation

#include <iostream>
#include <cmath>

using namespace std;

unsigned long long modExp(unsigned long long b, unsigned long long e, unsigned long long m)
{
    unsigned long long remainder;
    unsigned long long x = 1;

    while (e != 0)
    {
        remainder = e % 2;
        e= e/2;

        // These lines
        if(remainder==1)
            x=(unsigned long long)fmodl(((long double)x*(long double)b),(long double)m);
        b=(unsigned long long)fmodl(((long double)b*(long double)b),(long double)m);
    }
    return x;
}

int main()
{
    unsigned long long lastTen = 0,netSum=0;
    unsigned long long sec(unsigned long long,unsigned long long);

    for(int i=1;i<1001;i++)
    {
        lastTen = modExp(i,i,10000000000);
        netSum += lastTen;
        netSum %= 10000000000;
        cout << lastTen << endl ;
    }

    cout << netSum%10000000000 << endl;
    cout << sizeof(long double) << endl;
    return 0;
}

这是我计算一系列和的最后十位数的程序。它使用算术指数技术来计算最后10位数。它适用于10 ^ 9。但是当我去10 ^ 10时它会崩溃。

因此,为了使用更大尺寸的数据类型,我已将数字转换为long double并乘以它们(这将再次产生long double),因此如果我们对此数字采用模数,我们将得到正确的答案。但我没有得到正确的答案它导致同样的错误答案。

我想做这样的事情就像这样

  • 一个无符号长long是8个字节,因为我正在修改我会得到一个大数字作为一个10位数字所以乘以2,十位数字不适合无符号长long所以它将循环使用unsigned long long
  • 所以对于上面这点,我将无符号long long转换为long double(12个字节),因为它有很大的空间,所以它足够大,可以容纳2位数字的20位数产品

任何人都可以说这个逻辑中的缺陷是什么?

1 个答案:

答案 0 :(得分:2)

公共long double实现不能完全代表所有20位十进制数。

long double的特征并不完全由C ++标准决定,并且您没有说明您正在使用的实现。

long double的一个常见实现使用64位有效数字。虽然它可以存储在十二个字节中,但它只使用十个,其中16个用于符号和指数,剩余64个用于有效数字(包括一个显式的前导位)。

64位有效数字可以表示没有错误的整数,最多2 64 ,大约是1.845•10 19 。因此,它不能完全代表所有20位数字。