某些值导致无限循环

时间:2014-08-12 09:45:55

标签: javascript

我正在尝试构建一个用于能量计算的Javascript计算器,它主要起作用,但某些数字导致浏览器选项卡崩溃。我的jsfiddle:

http://jsfiddle.net/qdjfrjLr/

尝试在任何一天的放电时间输入8或任何时间输入15。

我怀疑问题与我的循环有关(在'做循环'评论下),但我看不出问题。循环的目的是确定liq_capacity需要什么值才能使fri_ending_balance变为(或接近)0。

function calculate() {
    // user inputs
    var sat_charge = parseInt(document.getElementById('sat_charge').value);
    var sat_discharge = parseInt(document.getElementById('sat_discharge').value);
    var sun_charge = parseInt(document.getElementById('sun_charge').value);
    var sun_discharge = parseInt(document.getElementById('sun_discharge').value);
    var mon_charge = parseInt(document.getElementById('mon_charge').value);
    var mon_discharge = parseInt(document.getElementById('mon_discharge').value);
    var tue_charge = parseInt(document.getElementById('tue_charge').value);
    var tue_discharge = parseInt(document.getElementById('tue_discharge').value);
    var wed_charge = parseInt(document.getElementById('wed_charge').value);
    var wed_discharge = parseInt(document.getElementById('wed_discharge').value);
    var thu_charge = parseInt(document.getElementById('thu_charge').value);
    var thu_discharge = parseInt(document.getElementById('thu_discharge').value);
    var fri_charge = parseInt(document.getElementById('fri_charge').value);
    var fri_discharge = parseInt(document.getElementById('fri_discharge').value);
    // back-end variables
    var sys_power_rating = 100;
    var noak = 1;
    var efficiency = 60; // expressed as a percentage
    var tank_escalation_factor = 0.9;
    var liq_reference_cost = 16300000;
    var experience_coefficient = 0.175; // expressed as a decimal
    var liq_reference_size = 300;
    var liq_and_pru_escalation_factor = 0.6;
    var power_recovery_reference_cost = 5705000;
    var power_recovery_reference_size = 3.5;
    var tank_coldstore_reference_size = 100;
    var liq_plant_specific_work = 0.2;
    var cost_of_tank_and_coldstore = 41;
    var pru_specific_work = liq_plant_specific_work * (efficiency / 100);
    if (liq_plant_specific_work < 0.1) {
        var tank_coldstore_reference_cost = cost_of_tank_and_coldstore * tank_coldstore_reference_size * liq_plant_specific_work;
    } else {
        var tank_coldstore_reference_cost = cost_of_tank_and_coldstore * tank_coldstore_reference_size * 0.1;
    }
    // do the loop
    var liq_capacity = 1;
    var fri_ending_balance = 1;
    while (fri_ending_balance < -0.1 || fri_ending_balance > 0.1) {
        var sat_initial_balance = 0;
        var sat_production = sat_charge * liq_capacity / 24;
        var sat_consumption = -1 * sat_discharge * sys_power_rating / pru_specific_work;
        var sat_ending_balance = sat_initial_balance + sat_production + sat_consumption;
        var sun_initial_balance = sat_ending_balance;
        var sun_production = sun_charge * liq_capacity / 24;
        var sun_consumption = -1 * sun_discharge * sys_power_rating / pru_specific_work;
        var sun_ending_balance = sun_initial_balance + sun_production + sun_consumption;
        var mon_initial_balance = sun_ending_balance;
        var mon_production = mon_charge * liq_capacity / 24;
        var mon_consumption = -1 * mon_discharge * sys_power_rating / pru_specific_work;
        var mon_ending_balance = mon_initial_balance + mon_production + mon_consumption;
        var tue_initial_balance = mon_ending_balance;
        var tue_production = tue_charge * liq_capacity / 24;
        var tue_consumption = -1 * tue_discharge * sys_power_rating / pru_specific_work;
        var tue_ending_balance = tue_initial_balance + tue_production + tue_consumption;
        var wed_initial_balance = tue_ending_balance;
        var wed_production = wed_charge * liq_capacity / 24;
        var wed_consumption = -1 * wed_discharge * sys_power_rating / pru_specific_work;
        var wed_ending_balance = wed_initial_balance + wed_production + wed_consumption;
        var thu_initial_balance = wed_ending_balance;
        var thu_production = thu_charge * liq_capacity / 24;
        var thu_consumption = -1 * thu_discharge * sys_power_rating / pru_specific_work;
        var thu_ending_balance = thu_initial_balance + thu_production + thu_consumption;
        var fri_initial_balance = thu_ending_balance;
        var fri_production = fri_charge * liq_capacity / 24;
        var fri_consumption = -1 * fri_discharge * sys_power_rating / pru_specific_work;
        fri_ending_balance = fri_initial_balance + fri_production + fri_consumption;
        liq_capacity = liq_capacity + 0.1;
    }
    var power_input = liq_capacity / 24 * liq_plant_specific_work;
    var liq_store_capacity_tonnes = Math.max(sat_production, sat_ending_balance, sun_production, sun_ending_balance, mon_production, mon_ending_balance, tue_production, tue_ending_balance, wed_production, wed_ending_balance, thu_production, thu_ending_balance, fri_production, fri_ending_balance);
    var liq_store_capacity_mwh = sys_power_rating * Math.max(sat_discharge, sun_discharge, mon_discharge, tue_discharge, wed_discharge, thu_discharge, fri_discharge);
    var liq_store_capacity_mwh_effective = tank_coldstore_reference_size * pru_specific_work;
    var liq_ecurve = liq_reference_cost * (Math.pow(noak, (Math.log(1-experience_coefficient)/Math.log(2))));
    var pru_ecurve = power_recovery_reference_cost * (Math.pow(noak, (Math.log(1-experience_coefficient)/Math.log(2))));
    var tank_and_coldstore_ecurve = tank_coldstore_reference_cost;
    var liq_cost_dollars = liq_ecurve * Math.pow((liq_capacity / liq_reference_size), liq_and_pru_escalation_factor);
    var pru_cost_dollars = pru_ecurve * Math.pow((sys_power_rating / power_recovery_reference_size), liq_and_pru_escalation_factor);
    var tank_and_coldstore_cost_dollars = (tank_and_coldstore_ecurve * 1000) * Math.pow((liq_store_capacity_tonnes / tank_coldstore_reference_size), tank_escalation_factor);
    var capex = liq_cost_dollars + pru_cost_dollars + tank_and_coldstore_cost_dollars;
    var cost_kw = capex / (sys_power_rating * 1000);
    var cost_kwh = capex / (liq_store_capacity_mwh * 1000);
    // slap those results on the page
    document.getElementById('liq_capacity').value = (liq_capacity).toFixed(0);
    document.getElementById('power_input').value = (power_input).toFixed(2);
    document.getElementById('liq_store_capacity_mwh').value = (liq_store_capacity_mwh).toFixed(0);
    document.getElementById('efficiency').value = efficiency + '%';
    document.getElementById('capex').value = (capex / 1000000).toFixed(1);
    document.getElementById('cost_kw').value = (cost_kw).toFixed(2);
    document.getElementById('cost_kwh').value = (cost_kwh).toFixed(2);
}

2 个答案:

答案 0 :(得分:0)

当然 - 你走了。它有点相似(我实际上从我的真实中移除了很多)所以不想太多地混淆页面,因此jsfiddle: - )

编辑:抱歉以错误的方式发布 - 我只是使用访客帐户在这里询问内容!这种方式至少意味着我的初始职位不会变得非常庞大。

(代码转储添加到问题中。)

编辑:非常感谢w3d!愚蠢的是,我曾经有更广泛的可接受结果(-0.9到0.9),但改变它以获得更准确的结果。无论如何它现在运行得很好,所以谢谢你的帮助:-)而且没有电子邮件通知!我只是不时地刷新。

答案 1 :(得分:0)

是的,问题在于你的循环:

while (fri_ending_balance < -0.1 || fri_ending_balance > 0.1) {

当您指定一天9的值时,&#34;放电&#34;那么fri_ending_balance的值永远不会接近0以满足你的循环条件。具体来说,fri_ending_balance永远不会变成&gt; = -0.1和&lt; = 0.1,所以你的循环永远不会结束。

如果您将这些结果记录到控制台,您可以看到发生了什么:

Iteration  fri_ending_balance
71418      -0.5999999802772891
71419      -0.36666664694234896
71420      -0.1333333136069541    /* Should stop here */
71421       0.10000001972525752
71422       0.3333333530601976
71423       0.5666666863955925
71424       0.8000000197278041