왜 parseInt (8,3) == NaN이고 parseInt (16,3) == 1입니까?


191

나는 이것을 읽고 있지만 parseInt에 기수 인수 장으로 쓰여진 것에 혼동됩니다.

parseInt (_, 3) 결과 표

왜이다 parseInt(8, 3)NaNparseInt(16, 3)1?

AFAIK 8 및 16 그렇게,베이스 3 수 없습니다 parseInt(16, 3)반환해야합니다 NaN너무

처음 10 개의 기본 -3 자연수


4
정적 타이핑 (또는 적어도 암시 적으로 정수를 문자열로 암시 적으로 변환하지 않음)으로 해결 된 또 다른 문제 : P
Navin

4
@Navin 이것은 정적 타이핑과 동적 타이핑과는 아무런 관련이 없습니다. 강력한 타이핑과는 달리 여기서 문제는 약합니다.
Sven Marnach

12
이 질문의 제목을 보았을 때, 나는 아마도 "loljavascript"때문이라고 생각했다. 나는 본능이 기본적으로 옳았다 고 판단하는 답을 봅니다.
벤 밀우드

답변:


373

이것은 사람들이 알고있을 때에도 항상 여행하는 것입니다. :-) 같은 이유로 parseInt("1abc")1이 반환 되는 것을 볼 수 있습니다 parseInt. 첫 번째 유효하지 않은 문자에서 멈추고 그 시점에있는 모든 것을 반환합니다. 구문 분석 할 유효한 문자가 없으면를 반환합니다 NaN.

parseInt(8, 3)" "8"base 3의 구문 분석"을 의미 합니다 (숫자 8를 문자열 로 변환합니다 . spec의 세부 사항 ). 그러나 기본 3에서, 한 자리 숫자는이다 0, 1하고 2. "9"8 진수 로 파싱하도록 요청하는 것과 같습니다 . 거기 없기 때문에 유효한 문자는, 당신은 있어요 NaN.

parseInt(16, 3)"16"기본 3에서 구문 분석 을 요청하고 있습니다. 구문 분석 할 수 있기 때문에 구문 분석 할 수 없기 때문에 1중단됩니다 6. 따라서를 반환합니다 1.


이 질문은 많은 관심을 끌고 있으며 검색 결과에서 높은 순위를 매길 수 있으므로 다음은 다양한 특성과 응용 프로그램 (여기서 내 대답에 대한 다른 답변)에서 JavaScript의 문자열을 숫자로 변환하는 옵션에 대한 설명입니다.

  • parseInt(str[, radix])-문자열의 시작 부분을 가능한 한 정수 (정수)로 변환하고 끝에 추가 문자를 무시합니다. 그래서 parseInt("10x")입니다 10; 는 x무시됩니다. 선택 사양 기수 (기수) 인수를 지원하므로 parseInt("15", 16)입니다 21( 15진수에서). 기수가없는 경우 문자열이 0x(또는 0X)로 시작하지 않으면 소수를 가정하고 ,이 경우에는 생략하고 16 진을 가정합니다. (일부 브라우저 0는 8 진수로 시작하는 문자열을 처리하는 데 사용되었습니다 . 해당 동작은 지정되지 않았 으며 ES5 사양에서 구체적으로 허용되지 않았습니다 .)NaN 구문 분석 가능한 숫자가 없으면 반환 합니다.

  • parseFloat(str)-와 parseInt같지만 부동 소수점 숫자를 수행하고 소수만 지원합니다. 다시 문자열에 추가 문자는 너무 무시하는 parseFloat("10.5x")것입니다 10.5합니다 (이 x무시됩니다). 단지 소수점이 지원되기 때문에, parseFloat("0x15")이다 0(상기 끝을 구문 분석 때문에 x). NaN구문 분석 가능한 숫자가없는 경우 반환 합니다.

  • 단항 ++str- (예를 들어, 암시 적 변환) 개종자 전체 , 부동 소수점 및 JavaScript의 표준 번호 표기 (단 자리와 소수점 포인트 = 소수점 사용 번호 문자열 0x프리픽스 = 헥스; 0o프리픽스 = 진수 [ES2015 +] 일부 구현으로 확장을 선행 0을 8 진 으로 취급 하지만 엄격 모드에서는 처리하지 않습니다. +"10x"이다 NaN(가) 때문에 x되어 있지 무시했다. +"10"이고 10, +"10.5"이며 10.5, +"0x15"이고 21, +"0o10"이다 8[ES2015 +]. 예상대로 +""0아닙니다 : 입니다 NaN.

  • Number(str)-암시 적 변환과 같지만 (예 : 단항 +과 같지만) 일부 구현에서는 속도가 느립니다. (중요하지는 않습니다.)


8
그래서 parseInt처음 사용하는 toString첫 번째 인수에? 말이 되겠네요.
evolutionxbox

16
@evolutionxbox : 예, 그것은 parseInt알고리즘 의 첫 단계입니다 : ecma-international.org/ecma-262/7.0/…
TJ Crowder

5
나는 그것이 첫 번째 로 바뀌고 나서 파싱이 소수점에서 멈춘 후에 123e-2제공 한다고 가정 합니까? 11.23
ilkkachu

6
"이것은 그들이 알고있을 때에도 사람들이 항상 여행하는 것"-> 이것이 버그라고 생각하는 유일한 사람입니까? 예를 들어 Java에서 동일한 작업을 수행하면 NumberFormatException매번 제공됩니다.
Wim Deblauwe

4
@SvenMarnach : 부분 parseInt(문자열의 첫 번째 인수를 강요)는 의미가 있습니다. 목적은 문자열을 정수 parseInt구문 분석 하는 것입니다 . 따라서 문자열이 아닌 것을 주면 문자열 표현을 시작하는 것이 좋습니다. 그 이후에 하는 일은 '다른 이야기'입니다.
TJ Crowder

54

같은 이유로

>> parseInt('1foobar',3)
<- 1

에서 doc 후 , parseInt문자열을 사용합니다. 과

string문자열 이 아닌 경우 문자열 로 변환됩니다

그래서 16, 8또는 '1foobar'첫 번째 문자열로 변환됩니다.

그때

parseInt지정된 기수에서 숫자가 아닌 문자가 발견 되면 해당 문자와 ​​모든 후속 문자를 무시합니다.

그것은 그것이 가능한 곳으로 변환된다는 것을 의미합니다. 는 6, 8그리고 foobar무시되며 이전에 무엇을 변환되어있다. 아무것도 없으면 NaN반환됩니다.


0
/***** Radix 3: Allowed numbers are [0,1,2] ********/
parseInt(4, 3); // NaN - We can't represent 4 using radix 3 [allowed - 0,1,2]

parseInt(3, 3); // NaN - We can't represent 3 using radix 3 [allowed - 0,1,2]

parseInt(2, 3); // 2   - yes we can !

parseInt(8, 3); // NaN - We can't represent 8 using radix 3 [allowed - 0,1,2]

parseInt(16, 3); // 1  
//'16' => '1' (6 ignored because it not in [0,1,2])    

/***** Radix 16: Allowed numbers/characters are [0-9,A-F] *****/ 
parseInt('FOX9', 16); // 15  
//'FOX9' => 'F' => 15 (decimal value of 'F')
// all characters from 'O' to end will be ignored once it encounters the out of range'O'
// 'O' it is NOT in [0-9,A-F]

몇 가지 예 :

parseInt('45', 13); // 57
// both 4 and 5 are allowed in Radix is 13 [0-9,A-C]

parseInt('1011', 2); // 11 (decimal NOT binary)

parseInt(7,8); // 7
// '7' => 7 in radix 8 [0 - 7]

parseInt(786,8); // 7 
// '78' => '7' => 7 (8 & next any numbers are ignored bcos 8 is NOT in [0-7])

parseInt(76,8); // 62 
// Both 7 & 6 are allowed '76' base 8 decimal conversion is 62 base 10 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.