1 Востаннє редагувалося Betterthanyou (26.10.2015 17:13:14)

Тема: pow: overflow error

Помилка pow: overflow error

long double S = 9999999999; /*Сума*/
long double n = 9999; /*Термін*/
long double M = 99; /*Річні (відсотків)*/
long double S2;
long double m=M/12/100;

S2=S*(m*pow((1+m),n))/(pow((1+m),n)-1);

Я хочу порахувати ануїтетні платежі для цього мені потрібно дізнатись коефіцієнт (формули брав звідси  http://byhgalter.com/anuїtetnij-sposib- … igidnishe/)

9999999999 * ( 0,0825 * pow( (1 + 0,0825 ), 9999 ) / ( pow( (1 + 0,0825), 9999 ) -1 )
1,0825^9999 - і як це порахувати ?

2

Re: pow: overflow error

Для с++ певно якісь ліби тра пошукати. Для python - numpy.
А взагалі, ви впевнені, шо у формулі все правильно? Бо там числа кілобайтні виходять, шо не є здорово для підрахунку якихось там платежів

3 Востаннє редагувалося Yola (26.10.2015 17:51:59)

Re: pow: overflow error

Мовиться про кредит на 9999 місяців із відсотковою ставкою 9999999999 * 12 річних, я правильно зрозумів?

4 Востаннє редагувалося koala (26.10.2015 18:03:50)

Re: pow: overflow error

"Річні" у вас не зовсім річні, не буду казати, які саме...
Оцінімо ваше число:
Сума ~ 1e10
Термін ~ 1e4
"Річний" коефіціент ~ 2
1e10*2^1e4 = 1e10*10^3e3=1e310
Для MSVC long double - синонім double, верхня межа якого - 1e308. Заїхали за межі. Особливо з урахуванням того, що ви спершу обчислюєте великі числа, а потім їх ділите.
Як вибиратися?
- взяти інший компілятор (більшість використовує для long double 80-бітні чи більші, їх вистачить);
- взяти якусь бібліотеку для довгої арифметики, на кшталт boost::multiprecision (чи написати власну);
- дуже обережно обчислювати це число, розклавши pow на цикл - я завищував параметри, можливо, воно таки буде на межі;
- обчислювати не число, а його логарифм;
- пояснити нам, що саме ви хочете зробити і нащо, можливо, будуть інші способи.

5

Re: pow: overflow error

До речі, якщо раптом ця формула виявиться правильною, то є один простий вихід. Значення буде наближене, але з дуже великою точністю.
Ось дивіться, якшо взяти за х оце ваше страшне pow( (1 + 0,0825), 9999 ), то тоді матимемо:

9999999999 * ( 0,0825 * x) / ( x - 1 )

При таких великих значеннях х, одиницею можна знехтувати, відповідно, просто скоротити на х. Тоді матимете:

9999999999 *  0,0825 = 824999999.9175

6 Востаннє редагувалося Betterthanyou (26.10.2015 20:38:42)

Re: pow: overflow error

Master_Sergius написав:

А взагалі, ви впевнені, шо у формулі все правильно?

Так це коефіцієнт там і має виходити таке число

Yola написав:

Мовиться про кредит на 9999 місяців із відсотковою ставкою 9999999999 * 12 річних, я правильно зрозумів?

майже так тільки річні 99%

koala написав:

- пояснити нам, що саме ви хочете зробити і нащо, можливо, будуть інші способи.

Ідея така якщо це значення обрахується правильно то всі решта будуть теж правильні так як програма приймає максимальне число для суми 10 цифр, для термін (місяців) 4, для річних (відсотків) 2

що до правильності програми я добавив скріншот зверху моя програма знизу калькулятор банку
сума 50000
річні 12%
термін 30 (місяців)
(http://www.oschadbank.ua/ru/private/loa … editType=2)

Post's attachments

Untitled.png 30.06 kb, 216 downloads since 2015-10-26 

7

Re: pow: overflow error

Це, можливо, буде для вас сюрпризом, але річний відсоток - це скільки ви отримаєте відсотків за рік, незалежно від форми виплат. Якщо виплати щомісячні і накопичувальні, то щомісячний відсоток буде меншим за річний/12.

8

Re: pow: overflow error

koala написав:

Якщо виплати щомісячні і накопичувальні

Аннуитет тобто сума до погашення завжди однакова (Це кредит)

koala написав:

щомісячний відсоток буде меншим за річний/12

так я переводив

long double m=M/12/100;

9

Re: pow: overflow error

Ок, тоді ще одну 12 в формулі загубили. А вам таки інший компілятор буде зручніший.

10

Re: pow: overflow error

koala написав:

Ок, тоді ще одну 12 в формулі загубили. А вам таки інший компілятор буде зручніший.

нічого я не загубив
Я її змінив
К=Р/12*(1+Р/12)(^n)/((1+Р/12)(^n)-1) -> S2=S*(m*pow((1+m),n))/(pow((1+m),n)-1);
так як інші формули не збігалися (ця S2-P*m)

int i=1;
for(;i<=n;i++)
{
    _Progress+=(100/n);
    Form3->Gauge1->Progress=_Progress;
    IoL+=P*m;
    Form3->StringGrid1->Cells[1][i]=i;
    Form3->StringGrid1->Cells[2][i]=FormatFloat("0.00",P);
    Form3->StringGrid1->Cells[3][i]=FormatFloat("0.00",S2-P*m);
    Form3->StringGrid1->Cells[4][i]=FormatFloat("0.00",P*m);
    Form3->StringGrid1->Cells[5][i]=FormatFloat("0.00",RK+K);
    Form3->StringGrid1->Cells[6][i]=FormatFloat("0.00",S2);
    P=P-(S2-(P*m));
    SV += RK+K;
    RK = 0;
}

/*pitsymki*/
Form3->StringGrid1->Cells[1][i]=i-1;
Form3->StringGrid1->Cells[2][i]=0;
Form3->StringGrid1->Cells[3][i]=FormatFloat("0.00",S);
Form3->StringGrid1->Cells[4][i]=FormatFloat("0.00",IoL);
Form3->StringGrid1->Cells[5][i]=FormatFloat("0.00",SV);
P_ = IoL+S;
Form3->StringGrid1->Cells[6][i]=FormatFloat("0.00",P_);
/*pitsymki*/

Що до компілятора я його не можу змінити так як це завдання з навчального закладу ми вивчаємо Builder C++

11

Re: pow: overflow error

створіть клас із полем типу

vector<char> _digits

який би реалізовував необхідні вам операції. Щоб піднесення до степеня не було надто довгим гляньте на Повторюване піднесення до квадрата