Помогите пожалуйста разобраться с калькулятором - рассчитываю аннуитет, происходит stack overflow. Если ставить маленькие числа - результаты выходят неправельные. Это изза неправильного выбора типов данных, или я ещё накосячил в формулах? Пожалуйста, подскажите несложную реализацию для работы с большими числами. Для проверки формул в атаче реализация в екселе и формула ежемесячного платежа
На самом деле у тебя при нажатии на кнопку выполнялись лишние действия, и все вылетало из-за несоответствия DecimalSeparator-а. Но эти преобразования не нужны, вот так может выглядеть эта самая процедура:
procedure TFCalc.BRaschClick(Sender: TObject);
function PMT(IR, NP, PV: real): real; begin result := (PV * IR) / (1 - power(1 + IR, -NP)); end;
var sum, stavka: extended; month: integer; Ejrasch: extended; begin sum := StrToFloat(ESum.Text); stavka := StrToFloat(EStavka.Text) * 0.01; month := StrToInt(Emonth.Text);
if RBAn.Checked=true then begin // цикл аннуитетного расчёта Ejrasch := Pmt(stavka / 12, month, sum); Annuite(sum, stavka, Ejrasch, month); end
else begin // цикл дифференциального расчёта
end;
end;
Кстати, в Annuite тоже надо внести несколько изменений:
procedure Annuite(summa, stavka, mesplatej: real; month: integer); var i: integer; ostn, ostk, vplpr, pgdolg: real; begin FCalc.SG.RowCount := month + 1; // А то вдруг я введу 60, как в примере?
for i := 1 to month do begin if i = 1 then ostn := summa else ostn := ostk; // Здесь была опечатка, надо if i = 1 vplpr := ostn * stavka / 12; pgdolg := mesplatej - vplpr; ostk := ostn - pgdolg;
FCalc.SG.Cells[0,i]:= inttostr(i); // <--- (2) - выводить текущий месяц, а не сколько всего месяцев FCalc.SG.Cells[1,i]:= floattostr(vplpr); FCalc.SG.Cells[2,i]:= floattostr(pgdolg); FCalc.SG.Cells[3,i]:= floattostr(mesplatej); FCalc.SG.Cells[4,i]:= floattostr(ostn); FCalc.SG.Cells[5,i]:= floattostr(ostk);