Тест: Можно ли доверять JavaScript?
Различаете parseInt и parseFloat?
Эта викторина проверит знания чисел в JavaScript: parseInt, parseFloat и BigInt. Разберём системы счисления, точность чисел с плавающей запятой и числовые ловушки языка.
Это всего лишь числа. Что тут сложного? 🤓
0.1 + 0.2 === 0.3Из‑за ошибок точности плавающих точек, 0.1 + 0.2 не равно точно 0.3. Из‑за того, как числа с плавающей запятой хранятся в памяти, результат равен 0.30000000000000004. Виноват стандарт IEEE 754 для работы с плавающей арифметикой — он не может точно представить некоторые числа. Это распространённая проблема во всех языках программирования. В конце концов вы столкнётесь с бесконечно повторяющейся десятичной дробью, и независимо от языка компьютер просто прекращает бесконечно генерировать цифры.
Некоторые языки, такие как Python и Java, имеют Decimal или BigDecimal для решения этой задачи, но в JavaScript их нет. Можно использовать библиотеки вроде big.js или decimal.js.
(Примечание: Некоторые языки предназначены для работы с дробями, мнимыми числами и т.п. на более высоком логическом уровне, сохраняя буквальные выражения. Но они всё равно сталкиваются с теми же проблемами точности плавающих точек на уровне аппаратуры.)
Что это может сделать?
5..toFixed(2).toFixed(2) возвращает строковое представление 5 с двумя знаками после запятой, поэтому результат — "5.00".
Двойная точка (5..toFixed(2)) — это «трюк», позволяющий обратиться к объектной модели числовых литералов.
Что получится?
parseInt("0x2A") === parseInt("2a", 16)Любая входная строка, начинающаяся с 0x, автоматически рассматривается как шестнадцатеричная (основание 16).
Поэтому это эквивалентно передаче radix 16. Таким образом, parseInt("0x2A") то же самое, что parseInt("2a", 16). (Регистронезависимо.)
[24, 'One', 42].map(parseInt)Второй аргумент parseInt (radix) совпадает с аргументом index, который передаёт метод массива. Это приводит к неожиданным результатам, так как parseInt("One", 1) возвращает NaN из‑за недопустимого ввода.
Первый элемент, 24, парсится как 24 в базе 0 (авто‑детект), поэтому остаётся 24. Второй элемент, 'One', парсится как NaN в базе 1. Третий элемент, 42, парсится в базе 2. В базе 2 строка '42' даёт NaN, так что результат [24, NaN, NaN].
Это распространённая ловушка при использовании parseInt с map. Если нужно превратить массив строк в числа, можно использовать .map(Number) для преобразования всей строки или явно указать основание при разборе числового префикса, например .map(x => parseInt(x, 10)).
Таблица сравнения
| Функция | parseInt | parseFloat | Number | BigInt |
|---|---|---|---|---|
| Игнорирует пробелы | ✅ | ✅ | ✅ | ✅ |
.map(FN) | ❌ | ☑️ | ✅ | ✅ |
| Поддерживает аргумент radix | ✅ | ❌ | ❌ | ❌ |
| Двоичные/восьмеричные/шестнадцатеричные префиксы в строках | Только 0x; префиксы 0b и 0o не распознаются автоматически | ❌ | ✅ | ✅ |
Недопустимые символы 42 oh no | 42 | 42 | NaN | SyntaxError |
Как у вас получилось? 🧐
Нужен перерыв после такой дозы бинарных данных?
Пфф, помните: делайте перерыв после навыков!
Загляните в мой зал и разберите ещё несколько задач! 💪
