Чому 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.