摘要: 小程序中的递归运算/二分查找算法/Maximum call stack size exceeded

场景:最近做一个车贷计算器, 其中存在一个公式如下:

 

    /****
总金额 * 月利率 * (1+月利率)^贷款期限 / ( (1+月利率)^贷款期限 — 1) = 月还款额
totalmoney --- 总金额
month_rate --- 月利率
year_rate ---- 月利率*12 --- month_rate*12
limit --- 贷款期限
monthsup --- 月还款额
共有4个变量totalmoney, month_rate, limit, monthsup
在知道totalmoney, month_rate, limit时计算monthsup是简单的, 但是由其他三个倒推出 monthsup 呢?
****/

利用数学方法解决这个问题可太难了,我在微博求助@毕导THU,毕导竟然给我解出来了。。。这清华的博士真是吓到我了。。

这里我们来想想怎么用代码来算出年利率/ 月利率

已知利率是0到1之间的数,大于0小于1

思路: 递归思想, 二分查找算法,

代码:

    function myfn(min, max, totalmoney, limit, monthsup){
let month_rate = (min + max)/2
let num = totalmoney * month_rate * Math.pow((1+month_rate),limit) / (Math.pow((1+month_rate),limit) - 1)
if(parseFloat(num.toFixed(2)) == parseFloat(monthsup.toFixed(2))) {
let monthRate = (Math.round(month_rate*10000)/100).toFixed(2)
let year_rate = 12 * month_rate
year_rate = (Math.round(year_rate*10000)/100).toFixed(2)
return [year_rate, monthRate]
}else if(parseFloat(num.toFixed(2)) > parseFloat(monthsup.toFixed(2))) {
max = (min + max)/2
return myfn(min, max, totalmoney, limit, monthsup)
}else if(parseFloat(num.toFixed(2)) < parseFloat(monthsup.toFixed(2))) {
min = (min + max)/2
return myfn(min, max, totalmoney, limit, monthsup)
}
}

注释: 这里其实就是一个递归的应用, 我们先取0和1的平均值, 带入公式中,将得到的值num与已知的月还款额进行比较, 若大于月还款额, 此时我们得到了一个更精确的范围, 即 月利率 的最大值为 0和1 的平均值, 然后_max = (min + max)/ 2,max =_max 再调用我们的函数myfn, 再次运算, 若num小于月还款额, 我们也能得到一个更精确的范围, 即 月利率的最小值为 0和 _max 的平均值, 。。。。这样直到已知的月还款额等于num, return 出年利率 / 月利率

重点提示: 细心的你可能已经发现了, 上面代码有许多的toFixed, 这不仅仅是根据产品需求所做的一个数据处理, 也是我们一定要做的一个限制,

如果不做这个限制的话, 递归函数将会进行巨量的计算,  直到num无限接近已知的月还款额, 但是我们并不需要得到这么精确的数据,只需要精确到小数点后两位或者三位, 四位即可,

(不加限制的时候,会出现这个错误, Maximum call stack size exceeded ,百度结果是 “超过最大调用堆栈大小”)

将代码搬到小程序上:

    myfn (min, max, totalmoney, limit, monthsup) {
totalmoney = parseFloat(totalmoney)
monthsup = parseFloat(monthsup)
let month_rate = (min + max)/2
let num = totalmoney * month_rate * Math.pow((1+month_rate),limit) / (Math.pow((1+month_rate),limit) - 1)
if(parseFloat(num.toFixed(2)) == parseFloat(monthsup.toFixed(2))) {
let monthRate = (Math.round(month_rate*10000)/100).toFixed(2)
let year_rate = 12 * month_rate
year_rate = (Math.round(year_rate*10000)/100).toFixed(2)
return [monthRate, year_rate]
}else if(parseFloat(num.toFixed(2)) > parseFloat(monthsup.toFixed(2))) {
max = (min + max)/2
return this.myfn(min, max, totalmoney, limit, monthsup) //************ return this.fn
}else if(parseFloat(num.toFixed(2)) < parseFloat(monthsup.toFixed(2))) {
min = (min + max)/2
return this.myfn(min, max, totalmoney, limit, monthsup)// ************* return this.fn
} },

在将代码搬到小程序时一定要注意, 递归函数内不符合条件时return fn 要改成 retrun this.fn , 否则 函数在进行完第一轮就不会再运行了, 因为它找不到fn, 我找个错误找了很久。。。。

就这吧, 新bug来了, 接着改bug。。。。

【微信小程序】 小程序中的递归运算/二分查找算法/Maximum call stack size exceeded的更多相关文章

  1. Python——递归、二分查找算法

    递归函数 1. 递归 (1)什么是递归:在函数中调用自身函数(2)最大递归深度:默认997/998——是Python从内存角度出发做的限制 n = 0 def story(): global n n+ ...

  2. too much recursion(太多递归)Uncaught RangeError: Maximum call stack size exceeded BootstrapValidator报错

    在BootstrapValidator中已默认遵守Bootstrap规则,form里的每个输入项目必需包含在类为form-group的标签里,否则BootstrapValidator中定义的field ...

  3. bootstrapValidator验证中Maximum call stack size exceeded

    Tip1:如果表单不是通过Bootstrap构建(即元素包含表单项且关联的label没有form-group类),可能会看到错误Uncaught RangeError: Maximum call st ...

  4. Java中的递归运算

    Java中的递归运算是一种在自己的方法内部调用自己的方法 递归的设计思想是:把一个复杂的问题,分解为若干个等同的子问题,重复执行,直到之问题能够简单到直接求解,这样复杂的问题就得以解决. 递归运算有两 ...

  5. 九度OJ 1349 数字在排序数组中出现的次数 -- 二分查找

    题目地址:http://ac.jobdu.com/problem.php?pid=1349 题目描述: 统计一个数字在排序数组中出现的次数. 输入: 每个测试案例包括两行: 第一行有1个整数n,表示数 ...

  6. 【C++】递归之二分查找

    简单查找的时间复杂度为O(n) 二分查找的时间复杂度为O(logn) 用递归实现二分查找: 基线条件:数组只包含一个元素.如果如果要查找的值与这个元素相同,就找到了:否则说明不在数组中. 递归条件:把 ...

  7. day17 python递归案例(二分查找,三级菜单)

    递归函数与三级菜单 menu = { '北京': { '海淀': { '五道口': { 'soho': {}, '网易': {}, 'google': {} }, '中关村': { '爱奇艺': {} ...

  8. java学习之—递归实现二分查找法

    /** * 递归实现二分查找法 * Create by Administrator * 2018/6/21 0021 * 上午 11:25 **/ class OrdArray{ private lo ...

  9. python基础编程: 编码补充、文件操作、集合、函数参数、函数递归、二分查找、匿名函数与高阶函数

    目录: 编码的补充 文件操作 集合 函数的参数 函数的递归 匿名函数与高阶函数 二分查找示例 一.编码的补充: 在python程序中,首行一般为:#-*- coding:utf-8 -*-,就是告诉p ...

随机推荐

  1. git使用cherry-pick和revert抢救错误代码提交

    大多数的新手在新接触git时都会出现这样的问题.代码写完了,提交到dev分支进行测试.一高兴忘记切回来,继续在dev分支开发,写完之后提交时猛的发现,我靠,我怎么在dev上面写代码,此时内心必然是一阵 ...

  2. vuex无法获取getters属性this.$store.getters.getCurChildId undefined

    问题描述 this.$store.getters.getCurChildId undefined 这是因为我们设置了命名空间namespaced: true, 在vuex官网中对命名空间的描述如下: ...

  3. python类模拟电路实现

    实现电路: 实现方法: class LogicGate(object): def __init__(self, n): self.name = n self.output = None def get ...

  4. 【转】Git使用教程之远程仓库

    1.远程仓库 在了解之前,先注册github账号,由于你的本地Git仓库和github仓库之间的传输是通过SSH加密的,所以需要一点设置: 第一步:创建SSH Key.在用户主目录下,看看有没有.ss ...

  5. 针对JCC指令练习的堆栈图

    堆栈图,主要目的就是练习一下JCC指令的熟练度,供参考 版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明.2019-09-10,23:41:41.作者By-----溺心与沉浮----博客园 ...

  6. 【PHP】关于系统性能追踪工具molten

    一.简介 关于molten的介绍网上有很多,是一个全链路追踪的工具,Molten可以看做是phptrace的的升级版(流行的php问题定位工具譬如phptrace,xhprof,这些工具可以自行Goo ...

  7. day05 作业

    猜年龄 ''' 输入姑娘的年龄后,进行以下判断: 1. 如果姑娘小于18岁,打印"不接受未成年" 2. 如果姑娘大于18岁小于25岁,打印"心动表白" 3. 如 ...

  8. python 模块、包

    #-----模块.包----- 模块: 一个.py 文件就称之为模块模块好处:1.提高代码可读性 2.编写代码不需要从零开始 python 模块: 1.python标准库 2.第三方模块 3.应用程序 ...

  9. Hebye 深度学习中Dropout原理解析

    1. Dropout简介 1.1 Dropout出现的原因 在机器学习的模型中,如果模型的参数太多,而训练样本又太少,训练出来的模型很容易产生过拟合的现象. 在训练神经网络的时候经常会遇到过拟合的问题 ...

  10. linux (08) nginx入门详解

    一. nginx 入门 nginx 入门学习 web服务器软件 windows IIS服务器 linux nginx apache 收费​lighthttp 公司的技术栈 收费版技术栈 apache ...