Чому parseInt (1/0, 19) повертає 18?


853

У мене дратує проблема в JavaScript .

> parseInt(1 / 0, 19)
> 18

Чому parseIntфункція повертається 18?


3
Цікаво. Але чому це набридає вам проблема? Чи доводиться вам керувати нескінченністю іншими способами? Якщо так, ifможе допомогти.
— Тило

254
Що за чорт ви навіть робили, це вимагало, щоб ви працювали або з базовими 19 числами, або з діленням на нуль !?
— Джек М

19
Коли ви заплутаєтесь у питаннях JS, просто поверніться до цієї цитати та пам’ятайте, що вся проклята мова була розроблена та впроваджена менш ніж за 10 днів (за словами людини, яка це зробила).
— tylerl

32
З FAQ: "Вам слід задавати лише практичні, відповідальні запитання на основі актуальних проблем, з якими ви стикаєтеся". Це насправді не "дратівлива проблема", з якою ви насправді стикаєтесь, це нереальний приклад, який вічно пливе по Інтернету .
— Джеремі Бенкс

2
python робить те саме: int ('I', 19) == 18
— oberhamsi

Відповіді:


1292

Результатом 1/0є Infinity.

parseIntтрактує свій перший аргумент як рядок, що означає, перш за все Infinity.toString(), називається, створюючи рядок "Infinity". Отже, це працює так само, як якщо б ви попросили його перетворити "Infinity"в базі 19 в десятковий.

Ось цифри в базі 19 разом з десятковими значеннями:

Base 19   Base 10 (decimal)
---------------------------
   0            0
   1            1
   2            2
   3            3
   4            4
   5            5
   6            6
   7            7
   8            8
   9            9
   a            10
   b            11
   c            12
   d            13
   e            14
   f            15
   g            16
   h            17
   i            18

Далі буде parseIntсканувати вхід, "Infinity"щоб знайти, яку частину його можна проаналізувати і зупинити після прийняття першої I(тому що nне є дійсною цифрою в базі 19).

Тому він поводиться так, як якщо б ви подзвонили parseInt("I", 19), що перетворює на десяткове 18 за таблицею вище.


32
@mithunsatheesh Спробуйте parseInt('Infini',24).
— Супр

112
@mithunsatheesh: Оскільки в базі 24 nтакож є дійсна цифра, тому вона фактично закінчується parseInt("Infini", 24).
— Джон

36
Чому хтось хоче «програмувати» мовою, яка так поводиться, це поза мною.
— Frans Bouma

45
@FransBouma: JS прекрасна по-своєму. І справді, жодна частина того, що відбувається тут, не є розумною в динамічній мові.
— Джон

59
@Jon: цей артефакт не є результатом динамічної мови; це результат невдалого набору тексту. У строго типізованій динамічній мові неявне перетворення Infinity (float) в "Infinity" (рядок) не відбудеться, щоб запобігти такому глупоті.
— Лежать Раян

225

Ось послідовність подій:

  • 1/0 оцінює до Infinity
  • parseIntчитає Infinityі радісно зазначає, що I18 в базі 19
  • parseInt ігнорує залишок рядка, оскільки його неможливо перетворити.

Зауважте, що ви отримаєте результат для будь-якої бази >= 19, але не для базових нижче. Для базових результатів >= 24ви отримаєте більший результат, оскільки він nстане дійсною цифрою в цьому пункті.


@Thilo BTW, що буде причиною, чому він може зупинитися на 19, якщо база більша? Чи знаєте ви, яка найбільша база, яку може створити JS?
— Арнтор

4
@Nordvind Найбільша база parseIntбуде прийнята 36, оскільки в англійському алфавіті є 26 літер, а умовою є використання цифр, а потім букв як набору дійсних цифр у даній базі.
— Крейг Citro

4
Щодо кулі №2, я можу запропонувати змінити Infinityна "Infinity"...
— CJBS

38

Щоб додати до наведених відповідей:

parseInt призначений для розбору рядків на числа (підказка в назві). У вашій ситуації ви взагалі не хочете робити будь-який синтаксичний аналіз, оскільки 1/0 - це вже число, тому це вибір дивної функції. Якщо у вас є номер (який ви робите) і хочете перетворити його на певну базу, замість цього слід скористатися toString з радіусом .

var num = 1 / 0;
var numInBase19 = num.toString(19); // returns the string "Infinity"

13

Щоб додати до наведених відповідей

parseInt(1/0,19) еквівалентно parseInt("Infinity",19)

Всередині бази 19 чисел 0-9і A-I (or a-i)є дійсними числами. Отже, з "Нескінченності" він бере Iбазу 19 і перетворюється на базу 10, яка стає 18 Тоді вона намагається прийняти наступний символ, тобтоn якого немає в базі 19, тому відкидає наступні символи (відповідно до поведінки JavaScript при перетворенні рядка в число )

Отже, якщо ви пишете parseInt("Infinity",19)АБО parseInt("I",19)АБО А parseInt("i",19)то результат буде однаковим, тобто 18.

Тепер, якщо ви пишете, parseInt("I0",19)результат буде 342 як I X 19 (the base)^1 + 0 X 19^0 = 18 X 19^1 + 0 X 19^0=18 X 19 + 0 X 1 =342

Аналогічно parseInt("I11",19) це призведе до6518

тобто

  18 X 19^2  +   1 X 19^1   +  1 X 19^0
= 18 X 19^2  +   1 X 19^1   +  1 X 19^0
= 18 X 361   +   1 X 19     +  1 X 1
= 6498  +  19  +  1
= 6518
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.