2012-02-15 34 views
16

Tôi tình cờ gặp vấn đề này với parseInt và tôi không chắc chắn tại sao điều này xảy ra.parseInt rounds không chính xác

console.log(parseInt("16980884512690999")); // gives 16980884512691000 
console.log(parseInt("169808845126909101"));​ // gives 169808845126909100 

tôi rõ ràng không nhấn bất kỳ giới hạn số lượng trong giới hạn Javascript (Number.MAX_VALUE = 1.7976931348623157e+308)

Chạy Win 7 64 bit nếu có vấn đề.

Tôi đang xem gì?

Fiddle

Trả lời

15

Đừng nhầm lẫn Number.MAX_VALUE với tối đa giá trị chính xác. Tất cả các số trong javascript được lưu trữ dưới dạng điểm nổi 64 bit, có nghĩa là bạn có thể nhận được số cao (và thấp), nhưng chúng sẽ chỉ chính xác đến một điểm nhất định.

Dấu phẩy động kép (nghĩa là Javascript) có 53 bit độ chính xác và độ chính xác, có nghĩa là số nguyên cao nhất/thấp nhất "chắc chắn chính xác" trong javascript là +/- 9007199254740992 (2^53). Các số trên/dưới có thể chỉ ra là chính xác (số đơn giản chỉ thêm số 0 vào cuối, bởi vì các bit số mũ có thể được sử dụng để biểu diễn điều đó).

Hoặc, theo các từ của ECMAScript: "Lưu ý rằng tất cả các số nguyên dương và âm có độ lớn không lớn hơn 2^53 thể hiện trong loại Số (thực sự, số nguyên 0 có hai biểu diễn, +0 và - 0). "

Cập nhật

Chỉ cần thêm một chút cho câu hỏi hiện có, spec ECMAScript đòi hỏi rằng nếu một số không thể thiếu chỉ còn ít hơn 22 chữ số, .toString() chí đầu ra nó trong ký hiệu thập phân tiêu chuẩn (ví dụ 169808845126909100000 như trong bạn thí dụ). Nếu nó có 22 chữ số trở lên, nó sẽ là đầu ra trong ký pháp khoa học chuẩn hóa (ví dụ: 1698088451269091000000 - một số 0 bổ sung - là đầu ra là 1.698088451269091e+21).

+0

Cả hai câu trả lời là đúng, tuy nhiên điều này giải thích nó trong chiều dài và cũng giải thích những gì sản lượng của tôi dường như bất thường có nghĩa là. – Mrchief

12

Từ this answer

Tất cả số trong Javascript là 64 bit "kép" chính xác động IEE754 một cách dấu chấm động.

Số nguyên dương lớn nhất có thể do đó chính xác được biểu thị là 2^53. Các bit còn lại được dành riêng cho số mũ.

2^53 = 9007199254740992

+1

Có; cũng xem http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html "Mỗi nhà khoa học máy tính nên biết gì về số học dấu chấm động" –

+0

Vậy tại sao tôi nhận được '169808845126909100' thay vì một số lỗi tràn hoặc cái gì khác? Đó là lớn hơn '9007199254740992' – Mrchief

+1

Xem câu trả lời của tôi. Bởi vì '1698088451269091' thấp hơn số đó và số 0 ở cuối là một phần của số mũ (tức là, nó có thể được viết là 1698088451269091 x 10^2). Nó không tràn, bởi vì đó là cách số học dấu chấm động hoạt động. Nó không quan tâm rằng bạn đang tìm kiếm số nguyên. – JimmiTh

Các vấn đề liên quan