Làm thế nào Lua xử lý cả số nguyên và số float?


11

Theo như tôi nhớ về lập trình, tôi được dạy không nên so sánh các số dấu phẩy động cho đẳng thức. Bây giờ, trong khi đọc Lập trình trong Lua về numberloại Lua , tôi thấy như sau:

Loại số đại diện cho số thực (dấu phẩy động chính xác kép). Lua không có loại số nguyên, vì nó không cần nó. Có một quan niệm sai lầm phổ biến về các lỗi số học dấu phẩy động và một số người lo ngại rằng ngay cả một mức tăng đơn giản cũng có thể trở nên kỳ lạ với các số có dấu phẩy động. Thực tế là, khi bạn sử dụng một số kép để biểu thị một số nguyên, không có lỗi làm tròn nào cả (trừ khi số lớn hơn 100.000.000). Cụ thể, một số Lua có thể đại diện cho bất kỳ số nguyên dài nào mà không làm tròn các vấn đề. Hơn nữa, hầu hết các CPU hiện đại thực hiện số học dấu phẩy động nhanh như (hoặc thậm chí nhanh hơn) số học số nguyên.

Điều đó có đúng với tất cả các ngôn ngữ không? Về cơ bản nếu chúng ta không vượt quá điểm nổi trong đôi, chúng ta có an toàn về số học không? Hoặc, để phù hợp hơn với tiêu đề câu hỏi, có điều gì đặc biệt mà Lua làm với numberloại của nó để nó hoạt động tốt như cả số nguyên và loại dấu phẩy động không?



@JoonasPulakka cảm ơn, đó là sự bổ sung khá có giá trị.
Petr Abdulin

Câu trả lời:


10

Lua tuyên bố rằng các số dấu phẩy động có thể biểu thị các số nguyên chính xác như các kiểu số nguyên có thể và tôi có xu hướng đồng ý. Không có đại diện không chính xác của một phần số phân đoạn để đối phó. Cho dù bạn lưu trữ một số nguyên trong một kiểu số nguyên hoặc lưu trữ nó trong phần tử của một số dấu phẩy động, kết quả là như nhau: số nguyên đó có thể được biểu diễn chính xác, miễn là bạn không vượt quá số bit trong phần tử , + 1 bit theo số mũ.

Tất nhiên, nếu bạn cố lưu trữ một số dấu phẩy động thực tế (ví dụ 12.345) trong một biểu diễn dấu phẩy động, tất cả các cược đều bị tắt, vì vậy chương trình của bạn phải rõ ràng rằng số đó thực sự là một số nguyên chính hãng không tràn vào mantissa, để coi nó như một số nguyên thực tế (nghĩa là so sánh với sự bình đẳng).

Nếu bạn cần độ chính xác số nguyên nhiều hơn thế, bạn luôn có thể sử dụng một thư viện chính xác tùy ý .

Đọc thêm
Giá trị tối đa của một số trong Lua là gì?


Thế còn đối số thứ hai của họ, tức là dấu phẩy động nhanh hay nhanh hơn số học số nguyên trong các CPU hiện đại? Âm thanh đáng ngờ với tôi, ngay cả khi sử dụng số dấu phẩy động để thực hiện số học số nguyên.
Andres F.

2
@AresresF. Tôi không thấy nó nhanh hơn thế nào, trừ khi bạn loại bỏ dàn diễn viên bằng cách sử dụng một loại số duy nhất thay vì hai.
Robert Harvey

Đã đồng ý. Không có ý nghĩa gì với tôi. Tôi tự hỏi nếu nó được đưa ra khỏi bối cảnh ...
Andres F.

1
Số nguyên đủ lớn không thể được lưu trữ chính xác trong một đối tượng dấu phẩy động. Một bit 64 bit doublecó khoảng 51 bit mantissa; số nguyên lẻ lớn hơn khoảng 2 ** 51 sẽ có lỗi vòng. Một số nguyên 64 bit có thể lưu trữ chính xác các giá trị số nguyên lớn hơn, vì nó không dành bất kỳ bit nào cho số mũ.
Keith Thompson

@KeithThndry: Tôi nghĩ rằng điều đó được ngụ ý trong câu trả lời của tôi khi tôi nói "được lưu trữ trong lớp phủ." Tuy nhiên, tôi sẽ chỉnh sửa câu trả lời để làm rõ.
Robert Harvey

5

Đôi được lưu trữ như một lớp phủ và số mũ. Xem định dạng để biết thêm thông tin. Về cơ bản, tất cả các số có dạng: mantissa * 2 số mũ . Đối với bất kỳ số nguyên nào nhỏ hơn 2 52 , số mũ sẽ bằng 0, làm cho bit mantissa bit-for-bit tương đương với số nguyên không dấu 52 bit. Một bit dấu riêng biệt được sử dụng để chỉ ra số âm.

Trong thực tế, thậm chí một số nguyên lớn hơn 2 52 có thể được biểu diễn một cách chính xác, miễn là tất cả các chữ số quá khứ 52 nd là số không. Ngoài ra, một số phân số, như 0,5, có thể được biểu diễn chính xác. Chỉ khi phân số được lặp lại liên tục (như 1/3) trong cơ sở 2, hoặc nếu không yêu cầu quá nhiều bit vượt qua điểm cơ số mà bạn mất độ chính xác.


Không phải vì liên tục lặp lại số thập phân. Đó là bởi vì nhiều số thập phân (cơ số mười) không thể được biểu diễn chính xác như là lũy thừa của hai.
Robert Harvey

2
Trong cơ sở 2, các số không thể được biểu diễn chính xác sẽ liên tục lặp lại. Ví dụ: 0,1 thập phân trở thành 0,0 (0011) ở dạng nhị phân, với 0011 liên tục lặp lại.
Karl Bielefeldt

2
Đúng chính xác. Nhưng không lặp lại ở cơ sở 10. Lặp lại ở cơ sở 2.
Robert Harvey
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.