fmodl — модуль в длинном двойном

#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), поэтому, если мы возьмем модуль для этого числа, мы получим ответ правильно. Но я не получил правильный ответ снова, это вызывает тот же неправильный ответ.

Моя мысль сделать такую ​​вещь, как это

  • длинная длина без знака составляет 8 байтов, так как я работаю, я получу большое число в виде 10-значного числа, поэтому при умножении 2 десятизначные числа не будут помещаться в длинную строку без знака, поэтому она будет циклически повторяться в длинной без знака
  • поэтому для вышеупомянутого пункта я преобразую long без знака long в long double (который составляет 12 байтов), и, поскольку он имеет большой размер, он достаточно велик, чтобы вместить 20-значное произведение двух десятизначных чисел

Кто-нибудь может сказать, что является недостатком в этой логике?

0

Решение

Общее long double реализация не может точно представлять все 20-значные десятичные числа.

Характеристики long double не полностью определены стандартом C ++, и вы не указываете, какую реализацию вы используете.

Одна общая реализация long double использует 64-битное значение. Хотя он может храниться в двенадцати байтах, он использует только десять, и 16 из них используются для знака и показателя степени, оставляя 64 для значимого (включая явный ведущий бит).

64-битное значениеи может представлять целые числа без ошибок до 264, что составляет около 1,845 • 1019. Таким образом, он не может точно представлять все 20-значные числа.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]