Я читаю это, но меня смущает то, что написано в parseInt с главой аргумента radix
Почему это parseInt(8, 3)
→ NaN
и parseInt(16, 3)
→ 1
?
AFAIK 8 и 16 не являются номерами base-3, поэтому parseInt(16, 3)
должны возвращаться NaN
тоже
Я читаю это, но меня смущает то, что написано в parseInt с главой аргумента radix
Почему это parseInt(8, 3)
→ NaN
и parseInt(16, 3)
→ 1
?
AFAIK 8 и 16 не являются номерами base-3, поэтому parseInt(16, 3)
должны возвращаться NaN
тоже
Ответы:
Это то, о чем люди спотыкаются все время, даже когда знают об этом. :-) Вы видите это по той же причине 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
), и в этом случае она пропускает их и принимает шестнадцатеричное значение. (Некоторые браузеры использовали строки, начинающиеся с 0
восьмеричного; такое поведение никогда не указывалось, и было специально запрещено в спецификации ES5.) Возвращает, NaN
если не найдено разборчивых цифр.
parseFloat(str)
- Нравится parseInt
, но делает числа с плавающей запятой и поддерживает только десятичные. Снова дополнительные символы в строке игнорируются, parseFloat("10.5x")
как и 10.5
( x
игнорируется). Как только десятичный поддерживаются, parseFloat("0x15")
это 0
(поскольку анализ заканчивается на x
). Возвращает, NaN
если не найдено разборчивых цифр.
Унарный +
, например +str
- (например, неявное преобразование) Преобразует всю строку в число, используя числа с плавающей запятой и стандартную нотацию JavaScript (только цифры и десятичная точка = десятичная; 0x
префикс = шестнадцатеричный; 0o
префикс = восьмеричный [ES2015 +]; некоторые реализации расширяют его рассматривать ведущий 0
как восьмеричное, но не в строгом режиме). +"10x"
это NaN
потому , что x
это не игнорируется. +"10"
это 10
, +"10.5"
это 10.5
, +"0x15"
это 21
, +"0o10"
это 8
[ES2015 +]. Имеет Гоча: +""
это 0
не NaN
как вы могли бы ожидать.
Number(str)
- Точно так же, как неявное преобразование (например, как унарный +
выше), но медленнее в некоторых реализациях. (Не то чтобы это могло иметь значение.)
parseInt
первое использование toString
по первому аргументу? Это имело бы смысл.
parseInt
алгоритма: ecma-international.org/ecma-262/7.0/…
123e-2
дает, 1
так как он 1.23
сначала превращается в , а затем синтаксический анализ останавливается на десятичной запятой?
NumberFormatException
каждый раз.
parseInt
(приведение первого аргумента к строке) имеет смысл. Цель parseInt
состоит в том, чтобы разобрать строку в целое число. Так что, если вы даете ему что-то, что не является строкой, имеет смысл начинать с строкового представления. То, что он делает после этого, - целая «другая история»
По той же причине, что
>> parseInt('1foobar',3)
<- 1
В ДоПе , parseInt
принимает строку. И
Если строка не является строкой, то она преобразуется в строку
Итак 16
, 8
или '1foobar'
сначала преобразуется в строку.
затем
Если
parseInt
встречает символ, который не является цифрой в указанном основании, он игнорирует его и все последующие символы
Это означает, что он преобразуется туда, где может. Символы 6
, 8
и foobar
игнорируются, и преобразуется только то, что перед ними. Если ничего нет, NaN
возвращается.
/***** 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