Về việc xử lý số dấu phẩy động theo cách xác định
Điểm nổi là xác định. Vâng, nó nên được. Nó phức tạp.
Có rất nhiều tài liệu về số dấu phẩy động:
Và làm thế nào họ có vấn đề:
Để trừu tượng. Ít nhất, trên một luồng duy nhất, các hoạt động tương tự, với cùng một dữ liệu, xảy ra theo cùng một thứ tự, nên có tính xác định. Vì vậy, chúng ta có thể bắt đầu bằng cách lo lắng về đầu vào và sắp xếp lại.
Một đầu vào như vậy gây ra vấn đề là thời gian.
Trước hết, bạn nên luôn luôn tính cùng một dấu thời gian. Tôi không nói là không đo thời gian, tôi đang nói rằng bạn sẽ không dành thời gian cho mô phỏng vật lý, bởi vì sự biến đổi theo thời gian là một nguồn gây nhiễu trong mô phỏng.
Tại sao bạn đo thời gian nếu bạn không chuyển nó sang mô phỏng vật lý? Bạn muốn đo thời gian đã trôi qua để biết khi nào nên gọi một bước mô phỏng và - giả sử bạn đang sử dụng giấc ngủ - bao nhiêu thời gian để ngủ.
Do vậy:
- Đo thời gian: Có
- Sử dụng thời gian trong mô phỏng: Không
Bây giờ, hướng dẫn sắp xếp lại.
Trình biên dịch có thể quyết định f * a + b
giống như b + f * a
vậy, tuy nhiên có thể có kết quả khác. Nó cũng có thể biên dịch thành fmadd hoặc có thể quyết định lấy nhiều dòng như thế xảy ra cùng nhau và viết chúng bằng SIMD , hoặc một số tối ưu hóa khác mà tôi không thể nghĩ ra ngay bây giờ. Và hãy nhớ rằng chúng tôi muốn các hoạt động tương tự xảy ra trên cùng một đơn đặt hàng, lý do là chúng tôi muốn kiểm soát những hoạt động xảy ra.
Và không, sử dụng gấp đôi sẽ không cứu bạn.
Bạn cần phải lo lắng về trình biên dịch và cấu hình của nó, đặc biệt là để đồng bộ hóa các số dấu phẩy động trên mạng. Bạn cần có được các bản dựng để đồng ý làm điều tương tự.
Có thể cho rằng, viết lắp ráp sẽ là lý tưởng. Bằng cách đó bạn quyết định thao tác để làm. Tuy nhiên, đó có thể là một vấn đề cho việc hỗ trợ nhiều nền tảng.
Do vậy:
Trường hợp cho số điểm cố định
Do cách thức nổi được thể hiện trong bộ nhớ, các giá trị lớn sẽ mất độ chính xác. Lý do là giữ cho các giá trị của bạn nhỏ (kẹp) giảm thiểu vấn đề. Do đó, không có tốc độ lớn và không có phòng lớn. Điều đó cũng có nghĩa là bạn có thể sử dụng vật lý rời rạc vì bạn ít có nguy cơ bị đào hầm.
Mặt khác, các lỗi nhỏ sẽ tích lũy. Vì vậy, cắt ngắn. Ý tôi là, chia tỷ lệ và chuyển thành một kiểu số nguyên. Bằng cách đó bạn biết không có gì là xây dựng. Sẽ có các hoạt động bạn có thể làm với loại số nguyên. Khi bạn cần quay lại điểm nổi, bạn bỏ và hoàn tác chia tỷ lệ.
Lưu ý tôi nói quy mô. Ý tưởng là 1 đơn vị thực sự sẽ được biểu diễn dưới dạng sức mạnh của hai (ví dụ 16384). Dù đó là gì, hãy biến nó thành một hằng số và sử dụng nó. Về cơ bản, bạn đang sử dụng nó như là số điểm cố định. Trong thực tế, nếu bạn có thể sử dụng số điểm cố định thích hợp từ một số thư viện đáng tin cậy tốt hơn nhiều.
Tôi đang nói cắt ngắn. Về vấn đề làm tròn, điều đó có nghĩa là bạn không thể tin tưởng vào chút cuối cùng của bất kỳ giá trị nào bạn nhận được sau khi chọn. Vì vậy, trước quy mô diễn viên để có được nhiều hơn một chút so với mức bạn cần và cắt ngắn nó sau đó.
Do vậy:
- Giữ giá trị nhỏ: Có
- Làm tròn cẩn thận: Có
- Đã sửa số điểm khi có thể: Có
Đợi đã, tại sao bạn cần điểm nổi? Bạn có thể không làm việc chỉ với một loại số nguyên? Ô đúng rồi. Lượng giác và bức xạ. Bạn có thể tính toán các bảng cho lượng giác và độ phóng xạ và nướng chúng trong nguồn của bạn. Hoặc bạn có thể thực hiện các thuật toán được sử dụng để tính toán chúng với số dấu phẩy động, ngoại trừ sử dụng số điểm cố định thay thế. Có, bạn cần phải cân bằng bộ nhớ, hiệu suất và độ chính xác. Tuy nhiên, bạn có thể đứng ngoài số dấu phẩy động và duy trì tính quyết định.
Bạn có biết họ đã làm những thứ như vậy cho PlayStation gốc không? Hãy gặp con chó của tôi, các bản vá lỗi .
Nhân tiện, tôi không nói là không sử dụng dấu phẩy động cho đồ họa. Chỉ dành cho vật lý. Ý tôi là, chắc chắn, các vị trí sẽ phụ thuộc vào vật lý. Tuy nhiên, như bạn biết một máy va chạm không phải phù hợp với một mô hình. Chúng tôi không muốn xem kết quả cắt ngắn của các mô hình.
Do đó: SỬ DỤNG SỐ ĐIỂM CỐ ĐỊNH.
Để rõ ràng, nếu bạn có thể sử dụng trình biên dịch cho phép bạn chỉ định cách các điểm nổi hoạt động và điều đó là đủ cho bạn, thì bạn có thể làm điều đó. Đó không phải lúc nào cũng là một lựa chọn. Bên cạnh đó, chúng tôi đang làm điều này cho chủ nghĩa quyết định. Số điểm cố định không có nghĩa là không có lỗi, sau tất cả chúng có độ chính xác hạn chế.
Tôi không nghĩ rằng "số điểm cố định là khó" là một lý do tốt để không sử dụng chúng. Và nếu bạn muốn một lý do chính đáng để sử dụng chúng, đó là tính quyết định, đặc biệt là tính quyết định trên các nền tảng.
Xem thêm:
Phụ lục : Tôi đề nghị giữ cho kích thước của thế giới nhỏ. Như đã nói, cả OP ans Jibb Smart đều đưa ra quan điểm rằng việc di chuyển ra khỏi phao gốc có độ chính xác kém hơn. Điều đó sẽ có ảnh hưởng đến vật lý, một thứ sẽ được nhìn thấy sớm hơn nhiều so với rìa thế giới. Số điểm cố định, tốt, có độ chính xác cố định, chúng sẽ tốt như nhau (hoặc xấu, nếu bạn thích) ở mọi nơi. Điều này là tốt nếu chúng ta muốn chủ nghĩa quyết định. Tôi cũng muốn đề cập rằng cách chúng ta thường làm vật lý có đặc tính khuếch đại các biến thể nhỏ. Xem Hiệu ứng cánh bướm - Vật lý quyết định trong Máy tạo khối và Máy tạo hình không thể tin được .
Một cách khác để làm vật lý
Tôi đã suy nghĩ, lý do tại sao sai số nhỏ về độ chính xác trong các số dấu phẩy động được khuếch đại là bởi vì chúng ta đang thực hiện các bước lặp trên các số đó. Mỗi bước mô phỏng chúng tôi lấy kết quả của bước mô phỏng cuối cùng và thực hiện các công cụ trên chúng. Tích lũy lỗi ontop lỗi. Đó là hiệu ứng cánh bướm của bạn.
Tôi không nghĩ rằng chúng ta sẽ thấy một bản dựng bằng cách sử dụng một luồng trên cùng một máy mang lại đầu ra khác nhau cho cùng một đầu vào. Tuy nhiên, trên một máy khác, nó có thể, hoặc một bản dựng khác có thể.
Có một đối số để thử nghiệm ở đó. Nếu chúng tôi quyết định chính xác cách mọi thứ hoạt động và chúng tôi có thể kiểm tra phần cứng đích, chúng tôi không nên đưa ra các bản dựng có hành vi khác.
Tuy nhiên, cũng có một lập luận cho việc không làm việc ở xa mà tích lũy quá nhiều lỗi. Có lẽ đây là một cơ hội để làm vật lý theo một cách khác.
Như bạn có thể biết, có vật lý liên tục và rời rạc, cả hai đều hoạt động trên mức độ mỗi đối tượng sẽ tiến lên theo dấu thời gian. Tuy nhiên, vật lý liên tục có các phương tiện để tìm ra sự va chạm tức thời thay vì thăm dò các vật thể khác nhau có thể để xem liệu có xảy ra va chạm hay không.
Vì vậy, tôi đề xuất như sau: sử dụng các kỹ thuật vật lý liên tục để tìm ra khi nào sự va chạm tiếp theo của mỗi đối tượng sẽ xảy ra, với dấu thời gian lớn, lớn hơn nhiều so với một bước mô phỏng duy nhất. Sau đó, bạn thực hiện va chạm gần nhất ngay lập tức và tìm ra mọi thứ sẽ diễn ra ngay lập tức.
Vâng, đó là rất nhiều công việc của một bước mô phỏng duy nhất. Điều đó có nghĩa là mô phỏng sẽ không bắt đầu ngay lập tức ...
... Tuy nhiên, bạn có thể mô phỏng một vài bước mô phỏng tiếp theo mà không cần kiểm tra va chạm mỗi lần, bởi vì bạn đã biết khi nào xảy ra va chạm tiếp theo (hoặc không có va chạm nào xảy ra trong dấu thời gian lớn). Hơn nữa, các lỗi tích lũy trong mô phỏng đó là không liên quan vì một khi mô phỏng đạt đến dấu thời gian lớn, chúng ta chỉ cần đặt các vị trí mà chúng ta đã tính toán trước.
Bây giờ, chúng ta có thể sử dụng ngân sách thời gian mà chúng ta đã sử dụng để kiểm tra va chạm từng bước mô phỏng để tính toán va chạm tiếp theo sau khi chúng ta tìm thấy. Đó là chúng ta có thể mô phỏng trước bằng cách sử dụng dấu thời gian lớn. Giả sử một thế giới bị giới hạn phạm vi (điều này sẽ không hoạt động đối với các trò chơi lớn), nên có một hàng trạng thái trong tương lai cho mô phỏng, và sau đó mỗi khung hình bạn chỉ cần nội suy từ trạng thái cuối cùng sang trạng thái tiếp theo.
Tôi sẽ tranh luận để nội suy. Tuy nhiên, do có sự tăng tốc, chúng ta không thể đơn giản nội suy mọi thứ theo cùng một cách. Thay vào đó chúng ta cần nội suy có tính đến gia tốc của từng đối tượng. Đối với vấn đề đó, chúng tôi chỉ có thể cập nhật vị trí giống như cách chúng tôi thực hiện cho dấu thời gian lớn (điều đó cũng có nghĩa là nó ít bị lỗi hơn vì chúng tôi sẽ không sử dụng hai triển khai khác nhau cho cùng một chuyển động).
Lưu ý : Nếu chúng ta đang thực hiện các số dấu phẩy động này, cách tiếp cận này không giải quyết được vấn đề của các đối tượng có hành vi khác xa với nguồn gốc của chúng. Tuy nhiên, trong khi sự thật là độ chính xác bị mất đi càng xa khỏi nguồn gốc, thì điều đó vẫn mang tính quyết định. Trong thực tế, đó là lý do tại sao thậm chí không đưa nó lên ban đầu.
Phụ lục
Từ OP trong bình luận :
Ý tưởng là người chơi sẽ có thể lưu máy của họ ở một số định dạng (chẳng hạn như xml hoặc json), để vị trí và góc quay của từng mảnh được ghi lại. Tập tin xml hoặc json đó sau đó sẽ được sử dụng để tái tạo máy trên máy tính của người chơi khác.
Vì vậy, không có định dạng nhị phân, phải không? Điều đó có nghĩa là chúng ta cũng cần phải lo lắng bất cứ điều gì hay không các số dấu phẩy động được phục hồi khớp với bản gốc. Xem: Float Precision Revisited: Nine Digit Float Portability