공부혜옹

[Javascript] 1e3 === 1000 ? 본문

공부합시다/JavaScript

[Javascript] 1e3 === 1000 ?

Blair06 2022. 11. 8. 00:39

최근 구현중인 과제에서 세자릿수의 숫자를 사용자 표준입력으로 입력받는데 입력받은 값을 유효성 검사하고 예외처리 하는 과정에서 다시 알게된것을 포스팅한다

문제 상황

세자릿수를 입력받아야하기 때문에 특수문자나 문자가 입력되었을시 throw로 에러를 발생시켜주었는데 이 검사과정에서 나는 isNaN 함수를 사용하였다

if(isNaN(value)) throw ...

isNaN의 파라미터로 숫자가 아닌 그 어떤값을 넘겨주어도 Number(value) 처리하여 숫자로 변환한다.

이 과정에서 숫자나 문자열이 아닌 경우는 숫자가 아니라는 뜻의 NaN(Not a Number)값을 갖게 되고, NaN이 되면 isNaN 함수는 true를 return 한다.

내가 넘겨준 value는 문자열이었는데 테스트시 ‘1c4’ 혹은 ‘4]ㅈ’와 같이 숫자가 아닌 문자가 들어가 있는경우 잘 예외처리 하는것을 확인하였다. 그런데 마지막 테스트중 나는 ‘1e3’ 을 입력한 순간 예외처리 로직구현에 실수가 있음을 깨달았다

isNaN(’1e3’) === true

내가 입력한 ‘1e3’ 단순 문자열이지만 number로 캐스팅 하는 순간 1e3이 되어 실제 숫자값이 된다.

그 이유는 e는 왼쪽의 숫자에 오른쪽의 숫자만큼 10의 거듭제곱하는 기능이 있기때문이다.

보통 숫자가 커지면 0의 갯수가 헷갈리고 실수가 있을 수 있기 때문에 이러한 표현을 사용한다

1.23e6 === 1.23 * 1000000

따라서 내가 입력한 ‘1e3’은 숫자 변환으로 인해 사실 1000이 되었기때문에 에러발생으로 넘어가지 않은것이다.

입력자릿수를 제한하였기에 다른것들은 문제가 없었으나 아마 제한조건이 달랐다면 16진수, 8진수 등등 문제가 될뻔했다…

내가 해결한 방법

원래 유효성 검사 후 배열을 만들어 각 요소들을 숫자로 바꾸어 줬던 코드 순서를 뒤집어 배열 만든 후 유효성검사를 실행했다.

this.userNumber = [...value].map((elem) => parseInt(elem));
if (this.userNumber.includes(NaN)) throw "잘못된 입력값 입니다.";

이렇게 하면 앞선 1e3의 경우

[1, NaN, 3]으로 변환되고, 배열내에 NaN을 가지고 있는지 판별하여 걸러주었다.

아마 정규표현식을 사용하면 더 깔끔할지도 모르지만 나는 어차피 배열을 만들 필요가 있었기 때문에 이런식으로 해결하였다.

반응형
Comments