简体   繁体   中英

Javascript division returns incorrect numbers

I am trying to create a simple webpage for class where users can calculate baseball metric stats. I currently have the following HTML:

<div>
    <h2>BABIP calculator</h2>

    <p class="extra">If number of sacrifice flies is not known it can be left blank and the BABIP calculation should still be fairly accurate as sacrifice flies typically account for a very small amount of At-Bats</p>
    <form id="BABIPform">
        <div>
            <label for="hits">Hits</label>
            <input type="text" name="hits" id="hits" value="0" min="0" required>
        </div>
        <div>
            <label for="homeruns">Homeruns</label>
            <input type="text" name="homerunsBABIP" id="homerunsBABIP" value="0" min="0" required>
        </div>
        <div>
            <label for="atBats">At-Bats</label>
            <input type="text" name="atBats" id="atBatsBABIP" value="0" min="0" required>
        </div>
        <div>
            <label for="k">Strikeouts</label>
            <input type="text" name="k" id="k" value="0" min="0" required>
        </div>
        <div>
            <label for="sf">Sacrifice Flies</label>
            <input type="text" name="sf" id="sf" value="0" min="0">
        </div>
        <div>
            <label for="babip">BABIP</label>
            <input type="text" name="babip" id="babip" disabled>
        </div>
        <div>
            <input type="submit" value="Calculate" id="submitBABIP">
        </div>
    </form>
</div>
<div>
        <h2>ISO calculator</h2>

    <p class="extra">ISO is a metric used to determine a player's raw power ouput more accurately than the standard SLG % by disregarding singles</p>
    <form id="ISOform">
        <div>
            <label for="doubles">2B</label>
            <input type="text" name="doubles" id="doubles" value="0" min="0" required>
        </div>
        <div>
            <label for="triples">3B</label>
            <input type="text" name="triples" id="triples" value="0" min="0" required>
        </div>
        <div>
            <label for="homeruns">HR</label>
            <input type="text" name="homeruns" id="homerunsISO" value="0" min="0" required>
        </div>
        <div>
            <label for="atBats">At-Bats</label>
            <input type="text" name="atBats" id="atBatsISO" value="0" min="0" required>
        </div>
        <div>
            <label for="iso">ISO</label>
            <input type="text" name="iso" id="iso" disabled>
        </div>
        <div>
            <input type="submit" value="Calculate" id="submitISO">
        </div>
    </form>
</div>

And the following JS to go with it.

function calculateBABIP() {
    'use strict';
    var BABIP;
    var AB = document.getElementById('atBatsBABIP').value;
    var H = document.getElementById('hits').value;
    var HR = document.getElementById('homerunsBABIP').value;
    var K = document.getElementById('k').value;
    var SF = document.getElementById('sf').value;
    BABIP = ((H-HR)/(AB-K-HR+SF)) 
    BABIP = BABIP.toFixed(3);
    document.getElementById('babip').value = BABIP;
    return false;
}

function initBABIP() {
    'use strict';
    var BABIPform = document.getElementById('BABIPform');
    BABIPform.onsubmit = calculateBABIP;
}


function calculateISO() {
    'use strict';
    var ISO;
    var doubles = document.getElementById('doubles').value;
    var triples= document.getElementById('triples').value;
    var HR = document.getElementById('homerunsISO').value;
    var AB = document.getElementById('atBatsISO').value;
    ISO = ((doubles)+(2*triples)+(3*HR))/AB;
    ISO = ISO.toFixed(3);
    document.getElementById('iso').value = ISO;
    return false;
}

function initISO() {
    'use strict';
    var ISOform = document.getElementById('ISOform');
    ISOform.onsubmit = calculateISO;
}

The issue is different with the two forms. For my first form (BABIPform) I tested a simple example of 30 hits in 60 at-bats which should equate to .500 however it places extra 0s before the answer so it formats as 0.050.
For the ISOform, I entered 30 doubles, 5 triples, and 20 homeruns in 600 at-bats and the function returned 501.767 instead of .166. I searched pretty thoroughly in the questions here and didn't find anything that quite described the issue and have tried manipulating my equations but cannot find the cause. Any help or if someone knows a tool that will show me what is being executed a la python tutor type program that would be much appreciated.

You're running into a common JavaScript gotcha which is that + serves as both the addition operator and the string concatenation operator. When you pull the values out of the form, they are strings, and this expression:

AB - K - HR + SF

...returns "600" for the values you entered. This is literally the combination of the strings "60" and "0" . In other words, the subtractions are performed as you expect, but there's no addition (it's string concatenation).

To fix this, you should first convert all numeric strings to numbers (using, for example, parseInt );

Your second problem might look different, but it's caused by the same thing. You just need to convert your strings before performing arithmetic on them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM