Подтвердить что ты не робот

Почему это parseInt (8,3) == NaN и parseInt (16,3) == 1?

Я читаю этот, но меня смущает то, что написано в parseInt с аргументом radix chapter

таблица parseInt (_, 3) results

Почему существует parseInt(8, 3)NaN и parseInt(16, 3)1?

AFAIK 8 и 16 не являются номерами оснований-3, поэтому parseInt(16, 3) должен также возвращать NaN

первые десять базовых чисел 3-го поколения

4b9b3361

Ответ 1

Это то, что люди путешествуют все время, даже когда они знают об этом.:-) Вы видите это по той же причине parseInt("1abc") возвращает 1: parseInt останавливается с первым недопустимым символом и возвращает все, что у него есть в этой точке. Если для синтаксического анализа нет действительных символов, он возвращает NaN.

parseInt(8, 3) означает "разбор "8" в базе 3" (обратите внимание, что он преобразует число 8 в строку; подробности в спецификации). Но в базе 3 однозначные числа - это только 0, 1 и 2. Это как просить его разбор "9" в восьмеричном. Поскольку допустимые символы нет, вы получили NaN.

parseInt(16, 3) запрашивает его разбор "16" в базе 3. Поскольку он может анализировать 1, он делает, а затем останавливается на 6, потому что он не может его разобрать. Поэтому он возвращает 1.


Поскольку этот вопрос получает много внимания и может сильно занять место в результатах поиска, здесь приведено описание вариантов преобразования строк в числа в JavaScript с их различными идиосинкратиями и приложениями (снятыми с другого моего ответа здесь на SO)

  • parseInt(str[, radix]) - преобразует столько строк начала, сколько может, в целое (целое число) число, игнорируя лишние символы в конце. Итак, parseInt("10x") - 10; x игнорируется. Поддерживает необязательный аргумент radix (number base), поэтому parseInt("15", 16) - 21 (15 в шестнадцатеричном формате). Если нет оснований, принимает десятичное значение, если строка не начинается с 0x (или 0x), и в этом случае она пропускает их и принимает hex. (Некоторые браузеры использовали для обработки строк, начиная с 0, как восьмеричные, это поведение никогда не указывалось и было специально запрещено в спецификации ES5.) Возвращает NaN if не найдено никаких синтаксических символов.

  • parseFloat(str) - Как parseInt, но имеет числа с плавающей запятой и поддерживает только десятичные числа. Снова лишние символы в строке игнорируются, поэтому parseFloat("10.5x") есть 10.5 (x игнорируется). Поскольку поддерживается только десятичное число, parseFloat("0x15") составляет 0 (поскольку синтаксический анализ заканчивается на x). Возвращает NaN, если не найдено никаких синтаксических символов.

  • Унарный +, например. +str - (например, неявное преобразование) Преобразует всю строку в число с использованием чисел с плавающей запятой и стандартным номером JavaScript (только цифры и десятичная точка = десятичная; 0x prefix = hex; 0o prefix = восьмеричный [ES2015 + ]; некоторые реализации расширяют его, чтобы рассматривать ведущий 0 как восьмеричный, но не в строгом режиме). +"10x" NaN, потому что x игнорируется не. +"10" 10, +"10.5" is 10.5, +"0x15" is 21, +"0o10" is 8 [ES2015 +]. Имеет gotcha: +"" 0, а не NaN, как вы могли ожидать.

  • Number(str) - точно как неявное преобразование (например, как унарное + выше), но медленнее на некоторых реализациях. (Не то, чтобы это могло иметь значение.)

Ответ 2

По той же причине, что

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

В документе, parseInt берет строку. И

Если строка не является строкой, она преобразуется в строку

Итак 16, 8 или '1foobar' сначала преобразуется в строку.

Тогда

Если parseInt встречается символ, который не является цифрой в указанном радиусе, он игнорирует его и все последующие символы

Значение конвертируется туда, где это возможно. 6, 8 и foobar игнорируются, и преобразуется только то, что было раньше. Если ничего нет, возвращается NaN.