Search code examples
javascriptapidomparseint

JS - Math isn't coming out right


I'm building an app that displays the weather and converts the current temp from Fahrenheit to Celsius. For some reason, when the conversion takes place, the math isn't coming out right. Oddly, after clicking the button 5 - 6 times, it starts working correctly.

My best guess is that I'm doing something wrong with parseInt() or maybe a variable isn't being updated.

Thoughts?

function toggleUnits(){
  if(wUnit.innerHTML == "C"){
    var oldTemp = parseInt(wTemp.innerHTML, 10),
        newTemp = oldTemp * 9 / 5 + 32;
    wTemp.innerHTML= newTemp;
    wUnit.innerHTML = "F";
    unitToggle.innerHTML ="Switch to Celsius";
  }else{
    var oldTemp = parseInt(wTemp.innerHTML, 10),
        newTemp = (oldTemp-32) * 5 / 9;
    wTemp.innerHTML= newTemp;
    wUnit.innerHTML = "C";
    unitToggle.innerHTML ="Switch to Fahrenheit";
  }
}

CodePen: https://codepen.io/abenjamin/pen/ZojJLq


Solution

  • It is helpful to scale up your decimal values by a consistent multiplier and represent all numbers as integers. For example, use 806 degrees instead of 80.6 degrees (multiply by 10) for your temperature calculations. This is to avoid the nuances with floating-point math. In JavaScript we only have the floating-point data type for numeric values, but luckily integer math under the floating-point data-type is exact. Therefore scaling up decimal values to integers (e.g., 2550 degrees instead of 25.50 degrees ) resolves the issue.

    For example (converting from fahrenheit to celsius):

    console.log((80.6-32) * 5 / 9); // outputs 26.999999999999996
    

    Corrected with:

    console.log((806-320) * 5 / 9 / 10 ); // outputs 27
    

    The reason your calculator works correctly sometimes but not other times is because the temperature API sometimes returns integers, but other times returns decimal values.

    I wouldn't recommend using parseInt to resolve this issue because it will round decimal values and you'll lose precision.