[英]Certain values resulting in infinite loop
我正在嘗試構建一個用於能量計算的Javascript計算器,它通常可以正常工作,但是某些數字會導致瀏覽器標簽崩潰。 我的jsfiddle:
嘗試在一天的放電時間內輸入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);
}
喏,給你。 相當多(我實際上從我的實際內容中刪除了很多東西),所以不想讓頁面過於混亂,因此jsfiddle :-)
編輯:很抱歉以錯誤的方式發布-我只是使用訪客帳戶在此處詢問問題! 這樣至少意味着我的初始帖子不會變得異常龐大。
(代碼轉儲添加到問題。)
編輯:非常感謝w3d! 愚蠢的是,我過去的可接受結果范圍更廣(-0.9到0.9),但是為了獲得更准確的結果而對其進行了更改。 無論如何,現在一切都運行良好,所以謝謝您的幫助:-)不,沒有電子郵件通知! 我只是不時刷新。
是的,問題出在您的循環中:
while (fri_ending_balance < -0.1 || fri_ending_balance > 0.1) {
如果將“ Discharge”(放電)天的值指定為9
,則fri_ending_balance
的值永遠不會接近0來滿足循環條件。 具體來說, fri_ending_balance
永遠不會變為> = -0.1和<= 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.