Число слишком мало, чтобы сделать математику с - PullRequest
2 голосов
/ 11 июля 2019

Я создаю простое приложение на Angular, которое рассчитывает платежи по кредиту.Для расчета ежемесячного платежа мне нужно иметь дело с довольно небольшим числом.

Я пытался использовать «Большую» библиотеку, но безрезультатно, так как не понимал, как она работает.Typescript имеет только один «числовой» тип, поэтому использование числа с большим объемом памяти исключено.

Вот код:

calcDisFac(i: number, n: number) {
    console.log(i);
    console.log(n);

    const firstTerm = Math.pow((1 + i), n) - 1;
    console.log(firstTerm);
    const secondTerm = Math.pow((i * (1 + i)), n);
    console.log(secondTerm);
    return firstTerm / secondTerm;
}

Используйте пример, в котором i = (7.75 / 100) / 12 и n = 360

Ожидаемый результат равен 3300 илигде-то там, и проблема в том, что число настолько мало, что просто становится 0. Любая помощь приветствуется.

Ответы [ 2 ]

1 голос
/ 11 июля 2019

Вот ответ, который вы получите, когда выполните вычисление для secondTerm с WolframAlpha , который будет использовать символические вычисления там, где это необходимо для достижения большей точности, чем математика с плавающей точкой в ​​JavaScript: 4.46531771441003 × 10^ -788 .Это число настолько близко к нулю, что должно быть для вас предупреждением о том, что что-то не так с вашими вычислениями.

Результат, полученный из calcDisFac((7.75 / 100) / 12, 360) , будет что-то вроде 2.049241445165735 × 10 ^ 788 , который, хотя технически не бесконечен, достаточно близок, когда речь идет о чем-токак ежемесячный платеж.Это, безусловно, значительно больше, чем 3300 всего, что у меня есть в кошельке, включая атомы.

Резервное копирование ... математика, которую вы делаете, не рассчитывает платежи по кредитам для любого типа кредита, который я когда-либо видел.Вы можете сами получить формулу для ссуды с фиксированной ставкой с фиксированными ежемесячными платежами и начальным балансом, или вы можете получить ее где-нибудь, как статья Википедии об ипотечных калькуляторах .Я думаю, что это выглядело бы примерно так:

function loanPayment(
  initialBalance: number,
  interestRatePerPeriod: number,
  numberOfPayments: number
) {
  const accrual = Math.pow(1 + interestRatePerPeriod, numberOfPayments);
  const paymentRatio = (interestRatePerPeriod * accrual) / (accrual - 1);
  return paymentRatio * initialBalance;
}

Математика с плавающей точкой в ​​JavaScript должна быть более чем адекватной для выполнения этого расчета для разумных значений initialBalance, interestRatePerPeriod и numberOfPayments.И обратите внимание, что вам нужен начальный баланс для математики, чтобы иметь какой-либо смысл (оплата будет пропорциональна первоначальному балансу).

Итак, работая в обратном направлении от желаемого результата 3300, если начальный остаток займа примерно равен 460000, то вы получите:

console.log(loanPayment(460000, 7.75 / 100 / 12, 360)); /// 3295.496

Помогает ли это?Удачи!

Ссылка на код

0 голосов
/ 11 июля 2019

Расчет приводит к арифметическому понижению.Это означает, что согласно IEEE 754 ваш результат может рассматриваться как ноль.

Если вам нужны более точные вычисления, вы можете изменить способ их выполнения.Например, проверьте этот ответ: https://stackoverflow.com/a/9342513/11420760

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...