파크로그

JavaScript 숫자 범위 + falsy

Jamie 가 알고리즘을 푸시다가 Javascript 의 문법적 요소에 관하여 질문을 주셨다.

 

백준 문제를 푸시는데, 1 의 숫자가 늘어나면서 몇의 자리 숫자일 때 특정 숫자(n) 의 배수가 되는지를 찾는 문제였다.

 

ex)

n 이 3 일 때 111 은 3의 배수, 3자리 이므로 3,

n 이 7 일 때 111111 은 7의 배수, 6자리 이므로 6

 

여기서 1의 숫자가 늘어나는 것을 multiple 이라는 변수로 설정하고, multiple * 10 + 1 을 무한반복으로 찾을 때

똑같은 로직인 것 같은데 하나는 시간초과, 하나는 틀렸습니다 가 나온다는 것이었다.

// 틀렸습니다
while(true){
	if (!(+multiple % num)) return ~~
}


// 시간초과
while(true){
	if (+multiple % num === 0) return ~~
}

뭐가 문제일지 질문해주실 당시에는 모르겠었는데, 어제 예비군 가서 멍 때리면서 해당 문제에 대해서 생각해보다가 Javascript 에서 지원하는 유효숫자범위에 문제가 있는게 아닐까? 라는 생각이 들어서 몇 가지 시도를 해보았다.

 

우선 n 이 9903 , 9999 일 때로 테스트해보았을 때 똑같이 310 이라는 결과가 나왔다.

다른 수 임에도 같은 숫자가 나온다는게 상식적으로 이해가 되지 않아서 왜 하필 310 일까? 에 대해서 생각을 해보았다.

 

확인해본 결과 10 의 309 승일 때 Javascript 는 해당 숫자를 Infinity 로 변환한다.

Infinity 를 나머지연산(%) 을 하려고 하면 NaN 이라는 falsy 한 값이 나온다. 

위 조건문을 비교해보았을 때 여기서 NaN 이 나온다면 느낌표(!) 를 통한 형변환을 한다면 NaN 은 falsy 한 값이기 때문에 true 를 반환한다.

하지만 NaN === 0 은 아니기 때문에 아래 조건에서는 false 가 나오고, 그렇기 때문에 아래 조건은 무한반복하게 된다.

if(!NaN) === if (true) return // 여기서 return 됨

if(NaN === 0) === if(false) return // return 되지 않음

특정 부동소수점을 지날 때 정확한 숫자로 표현이 되지않는다는 점은 알았지만, 10의 309 승이 되었을 때 Infinity 가 된다는 것은 이번 기회에 알 수 있게 되었다.

profile

파크로그

@파크park

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!