javascript - 为什么这些 JavaScript 方程会输出不同(但几乎相同)的答案?

标签 javascript math

因此,我正在尝试绘制一段时间内的收入图表,其中包括“加薪”。

例如。我一年赚 100 美元,每年加薪 1%(非复利)。该图表将显示 future 50 年左右每年的总收入。 所以,100、201、303 等等。

我的问题是,为什么所有这些方程都得出几乎相同但不精确的答案。我猜我的逻辑可能是错误的,但我已经坚持了大约两周,看不到我的错误。

<小时/>
//This adds the income from 3 months at 1% to another 12 months at 1%

console.log(interestCalc(100.00 * (3.00/12), (1.00/365), ((365.00/12) * 3)) + interestCalc(100.00, (1.00/365), ((365.00/12) * 3) + 365));

//This adds the income from 4 months at 1% to another 11 months at 1%

console.log(interestCalc(100.00 * (4.00/12), (1.00/365), ((365.00/12) * 4)) + interestCalc(100.00 * (11.00/12), (1.00/365), ((365.00/12) * 4) + ((365.00/12) * 11)));

//This adds the income from 10 months at 1% to another 5 months at 1%   

console.log(interestCalc(100.00 * (10.00/12), (1.00/365), ((365.00/12) * 10)) + interestCalc(100.00 * (5.00/12), (1.00/365), ((365.00/12) * 10) + ((365.00/12) * 5)));

//This adds the income from 12 months at 1% to another 3 months at 1%

console.log(interestCalc(100.00, (1.00/365), 365) + interestCalc(100.00 * (3.00/12), (1.00/365), 365 + ((365.00/12) * 3)));


function interestCalc(principal, interestRate, time)
{
  interestRate = interestRate * 0.01;

  return principal + (principal * interestRate * time);
}

-------------------------------------------------------------------

结果:

126.3125

126.25694444444443

126.2152777777778

126.3125

考虑到所有方程都应该给出 15 个月时间段的收入,我不明白为什么它们都不是 126.3125。任何帮助将不胜感激。我想我只是在这里有点愚蠢,所以继续攻击我吧哈哈。

最佳答案

让我们先重新排列一下您的输入并使其“干燥”

由于time的目的是天数(使用整个月),因此传入月数,并让函数将其乘以365/12 - 在函数中它是 365/1200 因为它还可以处理利率除以 100

计算中的本金也乘以月份数,因此让我们传递这个数字,第一个数字为 3 和 12,第二个数字为 4 和 11,依此类推,该函数现在也将处理该数字 - 这是最后一个顺便说一下,函数中的* m/12.0

//This adds the income from 3 months at 1% to another 12 months at 1%

console.log(
    interestCalc(100.00, 3,  (1.00/365), 3) + 
    interestCalc(100.00, 12, (1.00/365), 15)
);

//This adds the income from 4 months at 1% to another 11 months at 1%

console.log(
    interestCalc(100.00, 4, (1.00/365), 4) + 
    interestCalc(100.00, 11, (1.00/365), 15)
);

//This adds the income from 10 months at 1% to another 5 months at 1%   

console.log(
    interestCalc(100.00, 10, (1.00/365), 10) + 
    interestCalc(100.00, 5, (1.00/365), 15)
);

//This adds the income from 12 months at 1% to another 3 months at 1%

console.log(
    interestCalc(100.00, 12, (1.00/365), 12) + 
    interestCalc(100.00,  3, (1.00/365), 15)
);


function interestCalc(principal, m, interestRate, time)
{
  return (principal + (principal * interestRate * time * 365 / 1200)) * m / 12.0;
}

这输出与您的代码相同(除了最低有效数字,因为操作顺序以及 JavaScript 中的浮点与任何其他浮点一样 - 但这对于问题来说无关紧要)

现在,让我们简化一下

删除常量,因为它们是...常量

function interestCalc(principal, m, interestRate, time)
{
  return (principal + (principal * interestRate * time)) * m;
}

由于 interestRate 和我编写它的方式 principal 始终相同,因此删除它们

function interestCalc(principal, m, interestRate, time)
{
  return time * m;
}

所以,现在的结果是

 3 *  3 + 12 * 15 === 189
 4 *  4 + 11 * 15 === 181
10 * 10 +  5 * 15 === 175
12 * 12 +  3 * 15 === 189

如果您认为所有 4 个结果都相同,那么您的计算就有缺陷

很明显,两个匹配的计算实际上也是错误的

话虽如此,我还没有尝试找出正确的公式,因为我不太确定你想要实现什么

再次阅读问题后,我看不出您的代码与您想要实现的目标有何关系

I'm assuming this is what you wanted to do - that you want to calculate wages when an increase happens after 3, 4, 10 or 12 months - i.e. the wage increase could be part way into the year

如果不增加,15 个月内每年 100 就是 100 * 15/12 = 125

因此,每次分割应产生高于 125 的值(因为增加),但随着您在较低速率下有更多时间,这些值将变得更接近 125

您预计 15 个月内的最大值为前 3 个月 25 加上接下来 12 个月的 101

最低为 12 个月 100 + 3 个月 101/4 25.25,总共 125.25

因此,所有计算结果必须介于 125.25 和 126.00 之间

使用上面的代码,并更改 interestCalc 函数:

console.log(
    interestCalc(100.00,  3, 0) + 
    interestCalc(100.00, 12, 1)
);

console.log(
    interestCalc(100.00,  4, 0) + 
    interestCalc(100.00, 11, 1)
);

console.log(
    interestCalc(100.00, 10, 0) + 
    interestCalc(100.00,  5, 1)
);

console.log(
    interestCalc(100.00, 12, 0) + 
    interestCalc(100.00,  3, 1)
);


function interestCalc(principal, time, interestRate) {
    return (principal + principal * interestRate / 100) * time / 12;
}

如您所见,它们都在该范围内

现在,让我们让它变得更聪明

console.log(calc(100,  3, 1, 15));
console.log(calc(100,  4, 1, 15));
console.log(calc(100, 10, 1, 15));
console.log(calc(100, 12, 1, 15));

function calc(base, firstYearMonths, increase, totalMonths) {
    return (base * firstYearMonths / 12) + (base * (increase + 100) / 100 * (totalMonths - firstYearMonths) / 12);
}

但这总共只允许 12 到 23 个月

所以,让我们让它变得更聪明,因为现在我们甚至可以管理两次或多次加薪(即跨越 2 次或更多工资加薪)

console.log(calc(100,  3, 1, 15));
console.log(calc(100,  4, 1, 15));
console.log(calc(100, 10, 1, 15));
console.log(calc(100, 12, 1, 15));

function calc(base, firstYearMonths, increase, totalMonths) {
    let ret = base * firstYearMonths / 12;
    totalMonths -= firstYearMonths;
    let year = 1;
    while(totalMonths > 0) {
        ret += base * (1 + (increase * year) / 100) * Math.min(totalMonths, 12) / 12;
        totalMonths -= 12;
        year += 1;
    }
    return ret;
}

关于javascript - 为什么这些 JavaScript 方程会输出不同(但几乎相同)的答案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55755872/

相关文章:

javascript - 在 Rails 中测试 JavaScript View

javascript - 如何在 React 中更改 CSS 根变量?

javascript - 缩小尺寸时如何将标签更改为下拉列表?

java - 旋转平面,使其法线与另一个平面的法线方向相同

c# - 继续我的上一个问题: Having trouble in calculating roots of a quartic equation in C#

javascript - 使用二维数组计算输赢

java - 旋转物体使其变小

javascript - 生成一个 10 的倍数的随机数

math - 如何在更高维度的超球面上均匀分布点?

javascript - 如何隐藏js dom中的内部元素