자바스크립트로 소숫점 계산을 하다보면 우리가 상식적으로 생각하는 값이 아닌 이상한 값이 나오는 경우가 간혹 있습니다.

아래의 경우를 한번 보시기 바랍니다.


<script language="javascript">
document.write(0.3 + 0.6);
// 우리는 결과가 0.9 나올것이라 생각하지만 자바스크립트로 계산하면 0.8999999999999999 나온다.

document.write(6.2 + 0.23);
// 우리는 결과가 6.43 나올것이라 생각하지만 자바스크립트로 계산하면 6.430000000000001 나온다.

document.write(8.21 + 0.23);
// 우리는 결과가 8.44 나올것이라 생각하지만 자바스크립트로 계산하면 8.440000000000001 나온다.

document.write(72 * 0.0055);
// 우리는 결과가 0.396 나올것이라 생각하지만 자바스크립트로 계산하면 0.39599999999999996 나온다.
</script>


위와 같은 문제를 해결하려면 소숫점 단위를 전부 정수로 바꾸어 계산한 다음 다시 소숫점 단위로 바꾸어 주면 해결됩니다.

아래와 같이 말입니다.


<script language="javascript">
document.write(((0.3 * 10) + (0.6 * 10)) / 10); // 결과 0.9
document.write(((6.2 * 100) + (0.23 * 100)) / 100); // 결과 6.43
document.write(((8.21 * 100) + (0.23 * 100)) / 100); // 결과 8.440000000000001
document.write(((72) * (0.0055 * 10000)) / 10000); // 결과 0.396
</script>


그런데 위의 값을 보면 8.21 + 0.23 에서 여전히 값이 이상하게 나오는게 보이실겁니다.

자바스크립트로 계산했을때 8.21 * 100 하면 821 이 나올것 같지만 821.0000000000001 이 나오기 때문입니다.

정수로 만들려 했는데 정수가 나오지 않는 경우를 대비하여 Math.round() 처리를 해주면 됩니다.

아래와 같이 말입니다.


<script language="javascript">
document.write((Math.round(0.3 * 10) + Math.round(0.6 * 10)) / 10);
document.write((Math.round(6.2 * 100) + Math.round(0.23 * 100)) / 100);
document.write((Math.round(8.21 * 100) + Math.round(0.23 * 100)) / 100);
document.write((Math.round(72) * Math.round(0.0055 * 10000)) / 10000);
</script>


자 이제 처리가 됐습니다.

그런데 이거 함수로 만들어서 관리하면 더 편하겠죠? 허접한 실력이지만 한번 만들어봤습니다.


<script language="javascript">
// 사용방법 (숫자1 , 숫자2 , 계산식 기호)
function NumCal(num1,num2,cal)
{
 if (!isNaN(num1) && !isNaN(num2))
 {
  var pattern = /\./;
  if (pattern.test(num1)) {
   var num1 = num1.toString();
   var a1 = num1.split(".");
   var b1 = a1[1].length;
  } else {
   var b1 = 0;
  }
  if (pattern.test(num2)) {
   var num2 = num2.toString();
   var a2 = num2.split(".");
   var b2 = a2[1].length;
  } else {
   var b2 = 0;
  }

  var cnt = (b1 > b2) ? b1 : b2;
  var cz = "1";

  for (var i=1; i<=cnt; i++) {
   cz += "0";
  }

  var cz1 = (b1 == 0) ? 1 : cz;
  var cz2 = (b2 == 0) ? 1 : cz;

  switch (cal)
  {
   case "+" :
    var z = (Math.round(num1 * cz1) + Math.round(num2 * cz2)) / cz;
   break;
   case "-" :
    var z = (Math.round(num1 * cz1) - Math.round(num2 * cz2)) / cz;
   break;
   case "*" :
    var z = (Math.round(num1 * cz1) * Math.round(num2 * cz2)) / cz;
   break;
   case "/" :
    var z = (Math.round(num1 * cz1) / Math.round(num2 * cz2)) / cz;
   break;
  }

  return z;
 }
 else
 {
  return false;
 }
}

document.write(NumCal(0.3,0.6,'+'));
document.write(NumCal(6.2,0.23,'+'));
document.write(NumCal(8.21,0.23,'+'));
document.write(NumCal(8.25252,0.23,'+'));
document.write(NumCal(72,0.0055,'*'));

</script>

반응형
,