Tại sao parseInt (1/0, 19) trả về 18?


853

Tôi có một vấn đề khó chịu trong JavaScript .

> parseInt(1 / 0, 19)
> 18

Tại sao parseInthàm trả về 18?


3
Hấp dẫn. Nhưng tại sao điều này là một vấn đề gây phiền nhiễu cho bạn? Bạn có phải xử lý Infinity theo những cách khác không? Nếu vậy, ifcó thể giúp đỡ.
Thilo

254
Cái quái gì mà bạn thậm chí đang làm mà yêu cầu bạn phải làm việc với các số cơ số 19 HOẶC chia cho số 0!?
Jack M

19
Khi bạn bối rối về JS, chỉ cần quay lại trích dẫn này và nhớ rằng toàn bộ ngôn ngữ chết tiệt đã được thiết kế và thực hiện trong vòng chưa đầy 10 ngày (theo người thực hiện nó).
tylerl

32
Từ FAQ: "Bạn chỉ nên hỏi những câu hỏi thực tế, có thể trả lời dựa trên những vấn đề thực tế mà bạn gặp phải." Đây thực sự không phải là một "vấn đề gây phiền nhiễu" mà bạn thực sự phải đối mặt, đó là một ví dụ phi thực tế đang trôi nổi trên internet mãi mãi .
Jeremy Banks

2
python cũng làm điều tương tự: int ('I', 19) == 18
oberhamsi

Câu trả lời:


1292

Kết quả 1/0Infinity.

parseIntcoi đối số đầu tiên của nó là một chuỗi có nghĩa là trước hết Infinity.toString()được gọi, tạo ra chuỗi "Infinity". Vì vậy, nó hoạt động tương tự như khi bạn yêu cầu nó chuyển đổi "Infinity"trong cơ sở 19 sang thập phân.

Dưới đây là các chữ số trong cơ sở 19 cùng với các giá trị thập phân của chúng:

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

Điều xảy ra tiếp theo là parseIntquét đầu vào "Infinity"để tìm phần nào có thể được phân tích cú pháp và dừng lại sau khi chấp nhận phần đầu tiên I(vì nkhông phải là chữ số hợp lệ trong cơ sở 19).

Do đó, nó hoạt động như thể bạn đã gọi parseInt("I", 19), chuyển thành số thập phân 18 theo bảng trên.


32
@mithuneditesh Hãy thử parseInt('Infini',24).
Supr

112
@mithuneditesh: Bởi vì trong cơ sở 24 ncũng là một chữ số hợp lệ, nên nó thực sự kết thúc parseInt("Infini", 24).
Jon

36
Tại sao một người nào đó muốn 'lập trình' bằng một ngôn ngữ như thế này lại vượt ra ngoài tôi.
Frans Bouma

45
@FransBouma: JS rất đẹp theo cách riêng của nó. Và thực sự, không có phần nào của những gì xảy ra ở đây là không hợp lý trong một ngôn ngữ năng động.
Jon

59
@Jon: tạo tác này không phải là kết quả của ngôn ngữ động; đó là kết quả của việc đánh máy lỏng lẻo. Trong ngôn ngữ động được gõ chính xác, việc chuyển đổi ngầm định của Infinity (float) thành "Infinity" (chuỗi) sẽ không xảy ra, để ngăn chặn sự điên cuồng này.
Lie Ryan

225

Đây là chuỗi các sự kiện:

  • 1/0 đánh giá Infinity
  • parseIntđọc Infinityvà vui vẻ ghi chú đó Ilà 18 trong cơ sở 19
  • parseInt bỏ qua phần còn lại của chuỗi, vì nó không thể được chuyển đổi.

Lưu ý rằng bạn sẽ nhận được kết quả cho bất kỳ cơ sở nào >= 19, nhưng không phải cho các cơ sở dưới đó. Đối với các cơ sở >= 24, bạn sẽ nhận được một kết quả lớn hơn, khi ntrở thành một chữ số hợp lệ tại thời điểm đó.


@Thilo BTW, lý do sẽ là gì, tại sao nó có thể dừng lại ở 19, nếu cơ sở lớn hơn? Bạn có biết, iterpret cơ sở lớn nhất có thể là gì không?
Arnthor

4
@Nordvind Cơ sở lớn nhất parseIntsẽ chấp nhận là 36, vì có 26 chữ cái trong bảng chữ cái tiếng Anh và quy ước là sử dụng các chữ số sau đó là các chữ cái làm tập hợp các chữ số hợp lệ trong cơ sở đã cho.
Craig Citro

4
Trên Infinity"Infinity"
gạch

38

Để thêm vào các câu trả lời trên:

parseInt được dự định để phân tích các chuỗi thành số (đầu mối nằm trong tên). Trong tình huống của bạn, bạn không muốn thực hiện bất kỳ phân tích cú pháp nào vì 1/0 đã là một số, vì vậy đây là một lựa chọn chức năng kỳ lạ. Nếu bạn có một số (mà bạn làm) và muốn chuyển đổi nó thành một cơ sở cụ thể, bạn nên sử dụng toString với một cơ số thay thế.

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

13

Để thêm vào các câu trả lời trên

parseInt(1/0,19) tương đương với parseInt("Infinity",19)

Trong cơ sở 19 số 0-9A-I (or a-i)là một số hợp lệ. Vì vậy, từ "Vô cực", nó mất Icơ sở 19 và chuyển đổi thành cơ sở 10 trở thành 18 Sau đó, nó cố gắng lấy ký tự tiếp theo tức nlà không có trong cơ sở 19 để loại bỏ các ký tự tiếp theo (theo hành vi chuyển đổi chuỗi của javascript thành số )

Vì vậy, nếu bạn viết parseInt("Infinity",19)HOẶC parseInt("I",19)HOẶC parseInt("i",19)kết quả sẽ giống nhau 18.

Bây giờ, nếu bạn viết parseInt("I0",19)kết quả sẽ 342I X 19 (the base)^1 + 0 X 19^0 = 18 X 19^1 + 0 X 19^0= 18 X 19 + 0 X 1 = =342

Tương tự, parseInt("I11",19)sẽ dẫn đến6518

I E

  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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.